This is the fourth day of my participation in the November Gwen Challenge. See details: The last Gwen Challenge 2021.

I recommend reading the first few articles

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, What is the callback hell for mastering the Promise implementation principle (3)

review

We have completed the promise of the base book, as follows

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){
    if (this.state === FULFILLED) {
      onFulfilled(this.value)
    }

    if (this.state === REJECTED) {
      onRejected(this.reason)
    }

    if (this.state === PENDING) {
      // If the state of the Promise instance is not determined at this time, we need to save onFulfilled and onRejected, and then invoke the promise instance after the state changes
      this.onResolvedCallbacks.push(() = > {
        onFulfilled(this.value)
      })
      this.onRejectedCallbacks.push(() = > {
        onRejected(this.reason)
      })
    }

  }
}
Copy the code

PromisethethenChain call mechanism

  • As you can see from the last introduction to callback Hell,promisethethenThe chain mechanism allows us to write asynchronous code in the same way that synchronous code is written,promisethethenChain mechanism as wellpromiseThe core of the implementation, which we will follow according toPeomise A+To continue to implement ourPeomise

thenMethod returns a normal value

    1. promiseThe instancethenMethod takes two parameters, one is the callback to execute after success (onFulfilled) one is a callback executed after a failure (onRejected), ifthenThe callback (successful or failed) returns a normal value (noPromiseThrow an error), and the result is passed to the next timethenThe successful callback.
    1. becausethenMethods are called chained, sothenMethod returns one at a timePromiseInstance.
    1. In the implementationonFulfilledwithonRejectedIf an exception occurs during execution, the exception will be thrown to the next timethenTo the failure of the callback.
  • The code implementation is as follows:
then(onFulfilled, onRejected){

  let promise = new Promise((resolve, reject) = > {
      
      switch(this.state){
        case FULFILLED:
            If an exception occurs during a callback, the exception will be thrown to the next failed callback of 'then'.
            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 a Promise
  return promise
} 
Copy the code
  • Now that we have a preliminary version of the THEN method, we can test it out

    let Promise = require('./promise/1.promise.js')
    
    let p = new Promise((resolve,reject) = > {
        resolve('success')
    })
    
    p.then(value= > {
      console.log('value',value);
      return 10000000000000
    },reason= > {
      console.log('reason',reason);
    }).then(value= > {
      console.log('value',value);
    },reason= > {
      console.log('reason',reason);
    })
    Copy the code
  • You can see from the print that our then method already satisfies a chaining call that returns a normal value

portal

Tear Promise from zero hand, master the realization of the Promise principle (1) of the basic structure of the Promise

Basic Version of Promise Implementation Basic Version of Promise Implementation (2) Basic Version of Promise Implementation Principle (3) : What is hell

Subsequent articles will continue to be written every day