“This is the fifth day of my participation in the November Gwen Challenge. See details of the event: The Last Gwen Challenge 2021”.

portal

From zero tear Promise, grasp the realization principle of Promise (1) the realization of the basic structure of the Promise from zero tear Promise, grasp the realization principle of Promise (2) the basic version of the Promise realization from zero tear Promise, Grasp the implementation principle of Promise (3) the callback hell is what to rip a Promise from zero, grasp the implementation principle of Promise (4) then method chain call preliminary implementation

review

After last time, our then method had an initial look, and our promise looked something like this:

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class Promise{
  constructor(executor){

    this.state = PENDING
    this.value = undefined
    this.reason = undefined
    / / store onFulfilled
    this.onResolvedCallbacks = []
    / / store onRejected
    this.onRejectedCallbacks = []
    const resolve = (value) = > {
      if (this.state === PENDING) {
        this.value = value
        this.state = FULFILLED
        // The promise instance will call ondepressing after its state changes
        this.onResolvedCallbacks.forEach(fn= > fn())
      }
    }

    const reject = (reason) = > {
      if (this.state === PENDING) {
        this.reason = reason
        this.state = REJECTED
        // onRejected called after the promise instance state changes
        this.onRejectedCallbacks.forEach(fn= > fn())
      }
    }
    try {
      // An error in the execution of the executor function will cause the Promise to fail
      executor(resolve,reject)
    } catch (error) {
      reject(error)
    }
  }
  then(onFulfilled, onRejected){

    let promise = new Promise((resolve, reject) = > {
        
        switch(this.state){
          case FULFILLED:
              try{
                let x = onFulfilled(this.value)
                resolve(x)
              } catch(e){
                reject(e)
              }   
              break
          case REJECTED:
              try{
                let x = onRejected(this.reason)
                resolve(x)
              } catch(e){
                reject(e)
              }   
              break
          default:
            this.onResolvedCallbacks.push(() = > {
              try{
                let x = onFulfilled(this.value)
                resolve(x)
              } catch(e){
                reject(e)
              }
            })
            this.onRejectedCallbacks.push(() = > {
              try{
                let x = onRejected(this.reason)
                resolve(x)
              } catch(e){
                reject(e)
              }
            })
        }
      
    })
    return promise
  }
}
Copy the code

thenThe method returnsPromise

  • If the callPromiseThe instancethenThe method returns aPromiseSo we need to judge thisPromiseIn the state.
    • ifPromiseIf it is successful, it will deliver the result of success tothenMethod returnPeomiseA successful callback;
    • ifPromiseIf it fails, it will pass on the cause of the failure tothenMethod returnPeomiseFailed to call back.
  • So ourthenMethod can’t simply pass the return value of its callback to thisthenMethod to returnPromiseIn the now.
  • So here’s a way to do itthenThe return value of the callback to the method we callresolvePromiseThis method is notPromiseMethods on this class.
  • For resolvePromises, this method is used to resolvethenThe return value of the callback function in the method, depending on what the return value isthenMethod to returnPromiseIn the state.
  • So we need four parameters,thenMethod to returnPromise,thenThe return value of the callback function in thex, to be returnedpromisetheresolveFunction andrejectFunction.
  • The corresponding THEN method also needs to be revamped.
const resolvePromise = (promise, x, resolve, reject) = >{}then(onFulfilled, onRejected){

    let promise = new Promise((resolve, reject) = > {
        
        switch(this.state){
          case FULFILLED:
              try{
                let x = onFulfilled(this.value)
                // Instead of simply resolve(x), resolve the return value through resolvePromise
                resolvePromise(promise, x, resolve, reject)
              } catch(e){
                reject(e)
              }   
              break
          case REJECTED:
              try{
                let x = onRejected(this.reason)
                resolvePromise(promise, x, resolve, reject)
              } catch(e){
                reject(e)
              }   
              break
          default:
            this.onResolvedCallbacks.push(() = > {
              try{
                let x = onFulfilled(this.value)
                resolvePromise(promise, x, resolve, reject)
              } catch(e){
                reject(e)
              }
            })
            this.onRejectedCallbacks.push(() = > {
              try{
                let x = onRejected(this.reason)
                resolvePromise(promise, x, resolve, reject)
              } catch(e){
                reject(e)
              }
            })
        }
      
    })
    return promise
  }
Copy the code

Here’s our completePromise, so long

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
const resolvePromise = (promise, x, resolve, reject) = >{}class Promise{
  constructor(executor){

    this.state = PENDING
    this.value = undefined
    this.reason = undefined
    / / store onFulfilled
    this.onResolvedCallbacks = []
    / / store onRejected
    this.onRejectedCallbacks = []
    const resolve = (value) = > {
      if (this.state === PENDING) {
        this.value = value
        this.state = FULFILLED
        // The promise instance will call ondepressing after its state changes
        this.onResolvedCallbacks.forEach(fn= > fn())
      }
    }

    const reject = (reason) = > {
      if (this.state === PENDING) {
        this.reason = reason
        this.state = REJECTED
        // onRejected called after the promise instance state changes
        this.onRejectedCallbacks.forEach(fn= > fn())
      }
    }
    try {
      // An error in the execution of the executor function will cause the Promise to fail
      executor(resolve,reject)
    } catch (error) {
      reject(error)
    }
  }
  then(onFulfilled, onRejected){

    let promise = new Promise((resolve, reject) = > {
        
        switch(this.state){
          case FULFILLED:
              try{
                let x = onFulfilled(this.value)
                resolvePromise(promise, x, resolve, reject)
              } catch(e){
                reject(e)
              }   
              break
          case REJECTED:
              try{
                let x = onRejected(this.reason)
                resolvePromise(promise, x, resolve, reject)
              } catch(e){
                reject(e)
              }   
              break
          default:
            this.onResolvedCallbacks.push(() = > {
              try{
                let x = onFulfilled(this.value)
                resolvePromise(promise, x, resolve, reject)
              } catch(e){
                reject(e)
              }
            })
            this.onRejectedCallbacks.push(() = > {
              try{
                let x = onRejected(this.reason)
                resolvePromise(promise, x, resolve, reject)
              } catch(e){
                reject(e)
              }
            })
        }
      
    })
    return promise
  }
}
Copy the code

Why is the callback (onFulfilled, onRejected) in the THEN method a microtask?

Consider the question in the picture below

The implementation of the resolvePromise is left for the next article

portal

From zero tear Promise, grasp the realization principle of Promise (1) the realization of the basic structure of the Promise from zero tear Promise, grasp the realization principle of Promise (2) the basic version of the Promise realization from zero tear Promise, Grasp the implementation principle of Promise (3) the callback hell is what to rip a Promise from zero, grasp the implementation principle of Promise (4) then method chain call preliminary implementation