- A Promise is a class that when you execute that class you pass in an executor and that executor executes immediately
- There are three states in Promise: successful depressing failed waiting pending
Pending -> depressing pending -> Rejected Once the state is determined, it cannot be changedCopy the code
- The resolve and reject functions are used to change state
resolve: fulfilled
reject: rejected
Copy the code
- What the then method does internally is determine the state and if the state is a successful call to a successful callback and if the state is a failure call to a failed callback the then method is defined in the prototype object
- Then a successful callback takes one parameter to indicate the value after success. Then a failed callback takes one parameter to indicate the reason for failure
- The then methods under the same Promise object can be called multiple times
- The then method can be called chained. The callback of the later THEN method returns the value of the callback of the previous THEN method
const PENDING = 'pending'; / / wait for
const FULFILLED = 'fulfilled'; / / success
const REJECTED = 'rejected'; / / fail
class MyPromise {
constructor (executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e); }}/ / promsie state
status = PENDING;
// Value after success
value = undefined;
// Cause of failure
reason = undefined;
// Successful callback
successCallback = [];
// Failed callback
failCallback = [];
resolve = value= > {
// If the state is not waiting to prevent the program from executing down
if (this.status ! == PENDING)return;
// Change the status to success
this.status = FULFILLED;
// Save the value after success
this.value = value;
// Determine if the successful callback exists
// this.successCallback && this.successCallback(this.value);
while(this.successCallback.length) this.successCallback.shift()()
}
reject = reason= > {
// If the state is not waiting to prevent the program from executing down
if (this.status ! == PENDING)return;
// Change the status to failed
this.status = REJECTED;
// Cause of save failure
this.reason = reason;
// Determine if the failed callback exists
// this.failCallback && this.failCallback(this.reason);
while(this.failCallback.length) this.failCallback.shift()()
}
then (successCallback, failCallback) {
// Parameters are optional
successCallback = successCallback ? successCallback : value= > value;
// Parameters are optional
failCallback = failCallback ? failCallback: reason= > { throw reason };
let promsie2 = new MyPromise((resolve, reject) = > {
// Determine the status
if (this.status === FULFILLED) {
setTimeout(() = > {
try {
let x = successCallback(this.value);
// Determine whether x is a normal value or a promise object
// Call resolve directly if it is a normal value
// If it is a Promise object, look at the results returned by promsie
// Call resolve or reject based on the result returned by the Promise object
resolvePromise(promsie2, x, resolve, reject)
}catch(e) { reject(e); }},0)}else if (this.status === REJECTED) {
setTimeout(() = > {
try {
let x = failCallback(this.reason);
// Determine whether x is a normal value or a promise object
// Call resolve directly if it is a normal value
// If it is a Promise object, look at the results returned by promsie
// Call resolve or reject based on the result returned by the Promise object
resolvePromise(promsie2, x, resolve, reject)
}catch(e) { reject(e); }},0)}else {
/ / wait for
// Store the success and failure callbacks
this.successCallback.push(() = > {
setTimeout(() = > {
try {
let x = successCallback(this.value);
// Determine whether x is a normal value or a promise object
// Call resolve directly if it is a normal value
// If it is a Promise object, look at the results returned by promsie
// Call resolve or reject based on the result returned by the Promise object
resolvePromise(promsie2, x, resolve, reject)
}catch(e) { reject(e); }},0)});this.failCallback.push(() = > {
setTimeout(() = > {
try {
let x = failCallback(this.reason);
// Determine whether x is a normal value or a promise object
// Call resolve directly if it is a normal value
// If it is a Promise object, look at the results returned by promsie
// Call resolve or reject based on the result returned by the Promise object
resolvePromise(promsie2, x, resolve, reject)
}catch(e) { reject(e); }},0)}); }});return promsie2;
}
finally (callback) {
return this.then(value= > {
return MyPromise.resolve(callback()).then(() = > value);
}, reason= > {
return MyPromise.resolve(callback()).then(() = > { throw reason })
})
}
catch (failCallback) {
return this.then(undefined, failCallback)
}
static all (array) {
let result = [];
let index = 0;
return new MyPromise((resolve, reject) = > {
function addData (key, value) {
result[key] = value;
index++;
if(index === array.length) { resolve(result); }}for (let i = 0; i < array.length; i++) {
let current = array[i];
if (current instanceof MyPromise) {
/ / promise object
current.then(value= > addData(i, value), reason= > reject(reason))
}else {
/ / common valuesaddData(i, array[i]); }}})}static resolve (value) {
if (value instanceof MyPromise) return value;
return new MyPromise(resolve= >resolve(value)); }}function resolvePromise (promsie2, x, resolve, reject) {
if (promsie2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))}if (x instanceof MyPromise) {
/ / promise object
// x.then(value => resolve(value), reason => reject(reason));
x.then(resolve, reject);
} else {
/ / common valuesresolve(x); }}module.exports = MyPromise;
Copy the code