当前位置:网站首页>Promise (try to implement a promise by yourself) more detailed comments and other interfaces are not completed yet. Let's continue next time.
Promise (try to implement a promise by yourself) more detailed comments and other interfaces are not completed yet. Let's continue next time.
2022-07-24 06:35:00 【LuciferDawnC】
// let myPromise;
// determine promise Three states of
let sum = 0;
const PENDING = 'pending',
FULFILLED = 'fulfilled',
REJECTED = 'rejected';
// First promise Can pass new Keyword execution , Here we use class Declare this custom method
class MyPromise {
RF_CB_LIST = [];
RR_CB_LIST = [];
_status = PENDING;
/*
When used, an asynchronous Function To send the Ajax request
*/
constructor (fn) {
/*
Here we initialize Promise Value
Set up init The interface will be exposed outside the instance object To prevent initialization from being called repeatedly It is also because init Initialization should not be called repeatedly. Change the state and put the method into the private domain for initialization
Initialization fetch Promise The state of The value of success The value of failure
*/
this.status = PENDING;
this._status = PENDING;
this.value = null;
this.reason = null;
/*
Here we are going to fn Function to call
because class in this Point to the problem
To prevent incoming resolve and reject Of this Caused by pointing problems status and value as well as reason If something goes wrong, here we are right this To deal with
*/
if (this.isFunction(fn)) {
try {
fn(this.resolve.bind(this), this.reject.bind(this));
} catch (error) {
this.reject(error);
}
}
}
// initialization promise
/* init() {
// Initialization fetch Promise Value
this.status = PENDING;
this.value = null;
this.reason = null;
} */
/*
* promise There are two status resetters resolve and reject
*/
resolve (value) {
// State judgement It can only be executed in the initial state
if (this.status = PENDING) {
this.value = value;
this.status = FULFILLED;
}
}
reject (reason) {
// State judgement It can only be executed in the initial state
if (this.status = PENDING) {
this.reason = reason;
this.status = REJECTED;
}
}
/*
promise There are two callback methods .then .catch
then Receive two parameters Successful callbacks and failed callbacks need to be called after the function resets the state
then and catch Will return a new promise
*/
then (onFulfilled, onRejected) {
// Judge whether the current incoming value meets the expectation ( Function type ) Otherwise, reset it to the default function
const realOnFulfilled = this.isFunction(onFulfilled) ? onFulfilled : (value) => {
return value
}
const realOnRejected = this.isFunction(onRejected) ? onRejected : (reason) => {
throw reason;
};
// const realOnFulfilled = isFunction(onFulfilled) ? onFulfilled : returnVal;
// const realOnRejected = isFunction(onRejected) ? onRejected : returnErr;
// console.log(onFulfilled, onRejected)
const promise = new MyPromise((resolve, reject) => {
/*
queueMicrotask You can start a micro task
realOnFulfilled or realOnRejected It's time to return to one promise
therefore x It should be a new promise example
promise At present then To be returned promise object
x It is the present. realOnFulfilled or realOnRejected Function should return promise example
resolve yes promise Successful status reset
reject yes promise Failed state reset
resolvePromise(promise, x, resolve, reject)
*/
const fulfilledQueueMicrotask = () => {
queueMicrotask(() => {
try {
const x = realOnFulfilled(this.value);
this.realOnFulfilled(promise, x, resolve, reject);
} catch (error) {
reject(error);
}
})
}
const rejectedQueueMicrotask = () => {
queueMicrotask(() => {
try {
const x = realOnRejected(this.reason);
this.resolvePromise(promise, x, resolve, reject);
} catch (error) {
reject(error);
}
})
}
switch (this.status){
case FULFILLED:
fulfilledQueueMicrotask()
break;
case REJECTED:
rejectedQueueMicrotask()
break;
case PENDING:
/*
because js Is the code executed synchronously If it is an asynchronous resolve perhaps reject
Then the state may not have changed when executing this code At this time, we need to save the incoming callback
Execute when the state changes introduce get set
*/
// Array is used because there will be xxx.then Multiple such call methods At this moment then It needs to be placed in the array to facilitate traversal calls
this.RF_CB_LIST.push(fulfilledQueueMicrotask)
this.RR_CB_LIST.push(rejectedQueueMicrotask )
}
})
return promise;
}
catch (onRejected) {
return this.then(null, onRejected);
}
get status () {
return this._status;
}
set status (val) {
this._status = val;
switch (val) {
case FULFILLED:
this.RF_CB_LIST.forEach((callback, index) => {
callback(this.value)
})
break;
case REJECTED:
this.RR_CB_LIST.forEach((callback, index) => {
callback(this.reason)
})
break;
}
return val;
}
isFunction (fn) {
return Object.prototype.toString.call(fn) === '[object Function]';
}
isObject (obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
resolvePromise (promise, x, resolve, reject) {
if (promise === x) {
return reject(new TypeError(' Report errors : There may be a repeated call loop '))
}
// If X What is passed in is custom Promise Method
if (x instanceof MyPromise) {
/*
perform x Of then Method , If there is a return value during execution res, Parse the return value res
*/
queueMicrotask(() => {
x.then(
(res) => {
this.resolvePromise(promise, res, resolve, reject)
}, reject
)
})
} else if (this.isObject(x) || this.isFunction(x)) {
// If x Is an object or function
if (x === null) {
// null Will also be judged as an object
return resolve(x);
}
let then = null;
try {
// hold x.then Assign a value to then
then = x.then;
} catch (error) {
// If you take x.then Throw an error when the value of e , with e Refuse for cause promise
return reject(error);
}
// If then Is the function
if (this.isFunction(then)) {
let called = false;
// take x As the scope of a function this call
// Pass two callback functions as arguments , The first parameter is called resolvePromise , The second parameter is called rejectPromise
try {
then.call(
x,
// If resolvePromise To value y Called for parameter , Then run resolvePromise
(y) => {
// You need a variable called To ensure that only one call .
if (called) return;
called = true;
this.resolvePromise(promise, y, resolve, reject);
},
// If rejectPromise According to the cause r Called for parameter , According to the reason r Refuse promise
(r) => {
if (called) return;
called = true;
reject(r);
});
} catch (error) {
// If the then Method threw an exception e:
if (called) return;
// Otherwise, we should e Refuse for cause promise
reject(error);
}
} else {
// If then It's not a function , With x Execute for parameters promise
resolve(x);
}
} else {
resolve(x)
}
}
}
const test = new MyPromise((resolve, reject) => {
// setTimeout(() => {
reject(111);
// }, 1000);
}).then(res => {console.log(res);}).catch(rej => {
console.log('catch----------catch', rej)
}).then(res => {console.log(res);}).catch(rej => {
console.log('catch----------catch2', rej)
}).catch(rej => {
console.log('catch----------catch2', rej)
}).catch(rej => {
console.log('catch----------catch2', rej)
})
边栏推荐
- Login page + summary
- NFS共享服务及实验
- Batch operation of generating MySQL statements from Excel
- CentOS操作系统安全加固
- Remember to get the password of college student account once, from scratch
- Flex layout
- go的环境搭建和起步
- Leetcode sword finger offer jz42 maximum sum of continuous subarrays
- MySQL Index & execution plan
- Batch implementation of key based authentication using sshpass
猜你喜欢

Common commands and package management of go language

Polkadot | interprets how liberty plan, which subverts traditional social media, will be launched in Poka

XML parsing

IP course (OSPF) comprehensive experiment

Remember to get the password of college student account once, from scratch

API process and code structure

Ia class summary (1)

go语言常用命令和包管理

【222】内存溢出及定位

Wasm vs EVM, Boca's choice predicts the future of the public chain
随机推荐
API process and code structure
Flex layout
rsync(一):基本命令和用法
[219] what is the difference between app testing and web testing?
Map the intranet to the public network [no public IP required]
Flink production environment configuration recommendations
Public access intranet IIS website server [no public IP required]
Login page + summary
Configure a fixed remote desktop address [intranet penetration, no need for public IP]
RESTful API介绍
history命令历史记录中加时间
联合国农产品数据分析
利用sshpass批量实现基于key验证
Responsive page
How to build a website full of ritual sense and publish it on the public website 1-2
Windows下Mysql5.7忘记root密码解决方法
Flink checkpoint configuration details
Install agent and proxy using custom ZABBIX package (version 4.0.5)
Remember 20 classic interview questions of performance test in three minutes
Common commands and package management of go language