Promise’s rationale

  1. Promise is a class that, when executed, is passed a function that executes immediately
  2. Promises come in three states
    • Pending waiting for
    • Fulfilled successfully
    • The Rejected failure
  3. There can only be two changes in state
    • From Pending to Fulfilled
    • From Pending to Rejected
    • The above state changes can only be one of two, once the state changes will not be modified
    • The resolve and Reject functions in a Promise are used to change the state
  4. Then executes functions by state
    • If the state is success, the success callback function is executed
    • If the state is failed, the failure callback function is executed

To determine the implementation of native Promise, the code native 🌰 is as follows:

const promise = new Promise((resolve, reject) => { resolve('yes'); reject('on'); }) promise.then(value => { console.log('resolve:', value); }, error => { console.log('reject:', error); // Output resolve: yesCopy the code

The realization of the Promise

1. Create a new MyPromise class and pass the executor function, which passes the resolve and reject methods

Class MyPromise {constructor(executor) {executor(); // create a new MyPromise class. // Execute executor(this.resolve, this.reject); Resolve =()=> {} reject =()=> {}}Copy the code

2. Add status management

Const PENDING = 'PENDING '; const FULFILLED = 'fulfilled'; const REJECTED = 'rejected'; Class MyPromise {constructor(executor) {this.status = PENDING; // Create a new MyPromise class. This. value = null; Reason = null; // The failed value executor(this.resolve, this.reject); Resolve =(value)=> {if(this.status === PENDING) {// If (this.status === PENDING) { This. Status = FULFILLED; this.value = value; } } reject =(reason)=> { if(this.status === PENDING) { this.status = REJECTED; this.reason = reason; }}}Copy the code

3. Implementation of the THEN method

class MyPromise { ... then =(onFulfilled, onRejected)=> { if (this.status === FULFILLED) { onFulfilled(this.value); If (this.status === REJECTED) {onRejected(this.reason);} else if (this.status === REJECTED) {onRejected(this.reason); // Call the failure callback and return the cause}}}Copy the code

4. Execute the code and verify the result

const promise = new MyPromise((resolve, reject) => {
    resolve('yes')
    reject('no')
})

promise.then(value => {
    console.log('resolve', value);
}, reason => {
    console.log('reject', reason);
})
// resolve yes
Copy the code

The execution result is as expected, here should be happy ~~

5. Add asynchronous logic

When setTimeout is introduced, setTimeout will be added to the asynchronous queue, and then will be executed before setTimeout. The status of the THEN method is pending, and there is no processing of pending state, so there is no output.

const promise = new MyPromise((resolve, reject) => { setTimeout(() => { resolve('yes') }, 2000); }) promise.then(value => { console.log('resolve', value); }, reason => { console.log('reject', reason); }) // There is no outputCopy the code

6. Handle pending logic and then chained calls

class MyPromise{ constructor(executor) { ... this.onFulfilledCallbacks = []; OnRejectedCallbacks = []; // Store the failed callback function... } resolve =(value)=> { if(this.status === PENDING) { ... this.onFulfilledCallbacks && this.onFulfilledCallbacks.forEach((onFulfilledCallback) => { onFulfilledCallback(value); }); } } reject =(reason)=> { if(this.status === PENDING) { ... this.onRejectedCallbacks && this.onRejectedCallbacks((onRejectedCallback) => { onRejectedCallback(reason); }); } } then =(onFulfilled, onRejected)=> { if (this.status === FULFILLED) { ... } else if (this.status === REJECTED) { ... } else if(this.status === PENDING) { this.onFulfilledCallback = onFulfilled; this.onRejectedCallback = onRejected; } } } const promise = new MyPromise((resolve, reject) => { setTimeout(() => { resolve('yes') }, 2000); }) promise.then(value => { console.log(1) console.log('resolve', value); }) promise.then(value => { console.log(2) console.log('resolve', value) }) // 1 // resolve yes // 2 // resolve yesCopy the code