1. The target
Understand the basic implementation principles of promises and properly understand and use promises
2. Implement a simplified version of Promise
2.1 Understand the functionality of Promises
Look at the use of Promise
const a = new Promise((resolve,reject) = > {});
a.then(a= > {
console.log('a',a)
})
Copy the code
-
Is a function that can be new (here using es6 calss)
-
Accept a callback with two arguments, resolve,reject;
Call resolve to customize the content you want to return, and state it from Pending –> Depressing
Call Reject to customize the error cause returned from pending –> rejectd
-
Executed immediately
-
There are three states
Status: PENDING depressing REJECTED
State flow:
pending ---> fulfilled pending ---> rejected Copy the code
-
Instance methods
5.1 then
-
Instance method, not mounted on Prototype;
-
Ondepressing onRejected;
5.2 resole
Call resolve to customize the content you want to return, and state it from Pending –> Depressing
5.3 reject
Call Reject to customize the error cause returned from pending –> rejectd
2.2 Implementation of building the initial MPromise class
-
Structural class
-
Class attribute
Value: a successful return value (undefined, thenable, promise) reason: Error return value Status: state resolve: the promise callback for the first parameter (the instance calls the fulfilled method with the fulfilled state) reject: the promise callback for the second parameter (the instance calls the fulfilled method with the fulfilled state)Copy the code
-
code
const PENDING = 'PENDING'; const REJECTED = 'REJECTED'; const FULFILLED = 'FULFILLED'; class MPromise{ constructor(fn) { this.value = undefined; this.reason = undefined; this.status = PENDING; } resolve(newValue) { if(this.status === PENDING) { // State can only change from one state to another, irreversibly this.status = FULFILLED; this.value = newValue; }}reject(newReason) { if(this.status === 'PENDING') { this.status = REJECTED; this.reason = newReason; }}}const testP = new MPromise((resolve,reject) = >{});console.log('testP',testP); // The state is pending Copy the code
2.3 Implement immediate implementation of promises
Now the test uses promise, which, according to the PROMSI specification, would immediately print 000, but it doesn’t.
Q: How do I execute anonymous functions (resolve,reject) => {}?
A: Do this in the constructor class
const testP = new MPromise((resolve,reject) = > {
console.log('000')});Copy the code
Modify the implementation code:
constructor(fn) {
this.value = undefined;
this.reason = undefined;
this.status = PENDING;
try { // try to prevent errors
fn(this.resolve.bind(this),this.reject.bind(this));
} catch (error) {
this.reject(error)
}
}
Copy the code
Test execution:
const testP = new MPromise((resolve,reject) = > {
console.log('000')});console.log('testP',testP); // The state is pending
const testP = new MPromise((resolve,reject) = > {
console.log('000')
resolve('ddd')});console.log('testP',testP); // This is a big pity
const testP = new MPromise((resolve,reject) = > {
console.log('000')
reject('wrong')});console.log('testP',testP); // The status is rejectd
Copy the code
Conclusion:
-
New PROMISE If resolve is not executed, reject is always pending
-
Perform resolve, and the state is depressing
-
Run reject. The status is rejected
2.4 implementation then
When will it be implemented? (Execute when the state changes to a final state, after resolve,reject)
then(onFulfilled,onRejected) {
if(this.status === 'FULFILLED') {
onFulfilled(this.value);
}
if(this.status === 'REJECTED') {
onRejected(this.reason); }}Copy the code
Test execution:
const testP = new MPromise((resolve,reject) = > {
console.log('000')
resolve('dddd')});const testPthen= testP.then((a,b) = > { // onRejected is not a function
console.log(The '-',a);
});
Copy the code
If the onfunction ledonRejected is not a function, a default function will be executed
isFun(fn) {
return typeof fn === 'function';
}
then(onFulfilled,onRejected) {
if(this.status === FULFILLED) {
const isOnFulfilled = this.isFun(onFulfilled)? onFulfilled:(value) = > value;
isOnFulfilled(this.value);
}
if(this.status === REJECTED) {
const isOnRejected = this.isFun(onRejected)? onRejected:(reason) = > reason;
isOnRejected(this.reason); }}Copy the code
Test execution:
const testPthen= testP.then((ful,rej) = > {
console.log('ful',ful);
console.log('rej',rej);
});
Copy the code
2.5 Processing Asynchronous Tasks
When executing an asynchronous function in a promise, execute resolve,reject in asynchrony because promsie’s return state is pending and then will not execute.
For example:
const testP = new MPromise((resolve,reject) = > {
setTimeout(() = > {
console.log('111')
resolve('This value')},1000)});console.log('testP',testP); // pending
testP.then((ful) = > {
console.log('ful',ful) // undefined
})
Copy the code
How to solve it?
- Then, the state is pending, and the asynchronous task is placed in the corresponding queue.
- Resolve or Reject this asynchronous queue task
const PENDING = 'PENDING';
const REJECTED = 'REJECTED';
const FULFILLED = 'FULFILLED';
class MPromise{
constructor(fn) {
this.value = undefined;
this.reason = undefined;
this.status = PENDING;
this.onFulfillListCallback = []; // Asynchronous storage
this.onRejectedListCallback = []; // Asynchronous storage
try { // prevent errors
fn(this.resolve.bind(this),this.reject.bind(this)); // Bind this to prevent this from being lost
} catch (error) {
this.reject(error); }}resolve(newValue) {
if(this.status === PENDING) { // State can only change from one state to another, irreversibly
this.status = FULFILLED;
this.value = newValue;
this.onFulfillListCallback.forEach(fn= >fn()); }}reject(newReason) {
if(this.status === 'PENDING') {
this.status = REJECTED;
this.reason = newReason;
this.onRejectedListCallback.forEach(fn= >fn()); }}isFun(fn) {
return typeof fn === 'function';
}
then(onFulfilled,onRejected) {
const isOnFulfilled = this.isFun(onFulfilled)? onFulfilled:(value) = > value;
const isOnRejected = this.isFun(onRejected)? onRejected:(reason) = > reason;
if(this.status === FULFILLED) {
isOnFulfilled(this.value);
}
if(this.status === REJECTED) {
isOnRejected(this.reason);
}
if(this.status === PENDING) {
this.onFulfillListCallback.push(() = > {
isOnFulfilled(this.value);
});
this.onRejectedListCallback.push(() = > {
isOnRejected(this.reason); }); }}}Copy the code
Test code:
const testP = new MPromise((resolve,reject) = > {
setTimeout(() = > {
console.log('111')
resolve('This value')},1000)});console.log('testP',testP); // fulfilled
testP.then((ful) = > {
console.log('ful',ful) / / this value
})
Copy the code
2.6 Then returns a promise
Temporary unrealized
3. State flow of various methods of Promise
Test code 1:
const PromiseA = new Promise((resolve,reject) = >{});console.log('PromiseA',PromiseA); // pending
Copy the code
Promise.all: promise.all([PromiseA,PromiseB]);
- This is a big pity, all is a big pity
- There is a rejected,all
- Other cases are pending
Promise.race is whichever state is returned first
- Both are pending. Race is pending
- The first thing to return is fulfilled,race is fulfilled
- The first return is Rejected,race is Rejected
Promise. Allsettled will wait until all the results are finished, and then return all the values, which is a pity, and there is no rejected state
- There is a pending. Allsettled is pending
- This is a big pity, when all the states will return (depressing or Rejected), Allsettled is a big pity
Promise.any
- All pending, any is pending
- A. rejected B. any C. rejected D. any
- There is a big pity
Finally a method to execute without promsie state, only say without state
const PromiseA = new Promise((resolve,reject) = > {
reject('fff')
}).finally(() = > {});
Copy the code
-
Pending for