“This is the 11th day of my participation in the Gwen Challenge in November. See details: The Last Gwen Challenge in 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, Master the implementation principle of the Promise (3) callback hell is what from zero rip Promise, master the implementation principle of the Promise (4) then method chain call preliminary implementation from zero rip Promise, Grasp the implementation principle of the Promise (5) then method chain call advanced implementation from zero rip Promise, grasp the implementation principle of the Promise (6) then method callback why is asynchronous microtask from zero rip Promise, Then method chain call the core method resolvePromise from zero hand tear Promise, Then method chain call core method resolvePromise to explore from zero hand tear Promise, Master the implementation principle of Promise (9)then method chain call of the core method resolvePromise complete from zero hand tear Promise, master the implementation principle of Promise (10)then method complete

review

After 10 articles, our Promsie has been completed, and we are going to test whether our Promise conforms to the Promise A+ specification through A third-party NPM package.

Now all the promises look like this

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
const resolvePromise = (promise, x, resolve, reject) = > {
  / / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * to determine whether x and promsie the same promise, Prevent an infinite loop *********************//////*********
  if(x === promise) throw new TypeError('Chaining cycle detected for promise #<Promise>')
  // 1. Determine whether 'x' is a base type or a reference type.
  if(x ! = =null && /^(object|function)$/.test(typeof x)){
    let then 
    Then attribute (' x.chen ') on 'x'. Reject 'if an exception is reported
    try{
      then = x.then
    }catch(e){
      reject(e)
    }
    //3. Determine if 'then' is a function. If it is a function, then it is' Promise ', if not 'resolve'
    if(typeof then === 'function') {let called = false / / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * added a variable here * * * * * * * * * * * * * * * * * * * * * * * * * / / / / / /
      try{
        then.call(x, (y) = > {
          if(called) return / / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * added a variable here * * * * * * * * * * * * * * * * * * * * * * * * * / / / / / /
          called = true
          resolvePromise(promise, y, resolve, reject)
        },(r) = > {
          if(called) return/ / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * added a variable here * * * * * * * * * * * * * * * * * * * * * * * * * / / / / / /
          reject(r)
        })
      }catch(e){
        if(called) return/ / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * added a variable here * * * * * * * * * * * * * * * * * * * * * * * * * / / / / / /
        reject(e)
      }
    }else{
      resolve(x)
    }
  }else{
    // Base type data directly resolve
    resolve(x)
  }
}
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){
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v= > v
    onRejected = typeof onRejected === 'function' ? onRejected : err= > { throw err }
    let promise = new Promise((resolve, reject) = > {
        
        switch(this.state){
          case FULFILLED:
              setTimeout(() = > {
                try{
                  let x = onFulfilled(this.value)
                  resolvePromise(promise, x, resolve, reject)
                } catch(e){
                  reject(e)
                }
              })   
              break
          case REJECTED:
              setTimeout(() = > {
                try{
                  let x = onRejected(this.reason)
                  resolvePromise(promise, x, resolve, reject)
                } catch(e){
                  reject(e)
                }
              })   
              break
          default:
            this.onResolvedCallbacks.push(() = > {
              setTimeout(() = > {
                try{
                  let x = onFulfilled(this.value)
                  resolvePromise(promise, x, resolve, reject)
                } catch(e){
                  reject(e)
                }
              })
            })
            this.onRejectedCallbacks.push(() = > {
              setTimeout(() = > {
                try{
                  let x = onRejected(this.reason)
                  resolvePromise(promise, x, resolve, reject)
                } catch(e){
                  reject(e)
                }
              })
            })
        }
    })
    return promise
  }
}
Copy the code

The test process

    1. npm init --yesInitialize thepackage.json
    1. npm i promise-aplus-tests -DLocal installation testPromiseThird party package
    1. inindex.jsIn the file, put what we want to testPromiseAnd add the following code.
    • This code is very simplePromiseExtends a static method that returns an objectdfd.dfdPhi has three properties, one is phiPromsieInstance, and the other two are their counterpartsresolve,reject.
    • It’s essentially calling this method, and you can create onePromiseInstance, and return the instance.
    Promise.deferred = function(){
    let dfd = {}
    dfd.promise = new Promise((resolve,reject) = >{
          dfd.resolve = resolve;
          dfd.reject = reject;
      })
      return dfd;
    }
    Copy the code
    1. And then finally we get ourPromsie
    module.exports = Promise
    
    Copy the code

index.jsSuch a long

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
const resolvePromise = (promise, x, resolve, reject) = > {
  / / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * to determine whether x and promsie the same promise, Prevent an infinite loop *********************//////*********
  if(x === promise) throw new TypeError('Chaining cycle detected for promise #<Promise>')
  // 1. Determine whether 'x' is a base type or a reference type.
  if(x ! = =null && /^(object|function)$/.test(typeof x)){
    let then 
    Then attribute (' x.chen ') on 'x'. Reject 'if an exception is reported
    try{
      then = x.then
    }catch(e){
      reject(e)
    }
    //3. Determine if 'then' is a function. If it is a function, then it is' Promise ', if not 'resolve'
    if(typeof then === 'function') {let called = false / / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * added a variable here * * * * * * * * * * * * * * * * * * * * * * * * * / / / / / /
      try{
        then.call(x, (y) = > {
          if(called) return / / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * added a variable here * * * * * * * * * * * * * * * * * * * * * * * * * / / / / / /
          called = true
          resolvePromise(promise, y, resolve, reject)
        },(r) = > {
          if(called) return/ / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * added a variable here * * * * * * * * * * * * * * * * * * * * * * * * * / / / / / /
          reject(r)
        })
      }catch(e){
        if(called) return/ / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * added a variable here * * * * * * * * * * * * * * * * * * * * * * * * * / / / / / /
        reject(e)
      }
    }else{
      resolve(x)
    }
  }else{
    // Base type data directly resolve
    resolve(x)
  }
}
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){
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v= > v
    onRejected = typeof onRejected === 'function' ? onRejected : err= > { throw err }
    let promise = new Promise((resolve, reject) = > {
        
        switch(this.state){
          case FULFILLED:
              setTimeout(() = > {
                try{
                  let x = onFulfilled(this.value)
                  resolvePromise(promise, x, resolve, reject)
                } catch(e){
                  reject(e)
                }
              })   
              break
          case REJECTED:
              setTimeout(() = > {
                try{
                  let x = onRejected(this.reason)
                  resolvePromise(promise, x, resolve, reject)
                } catch(e){
                  reject(e)
                }
              })   
              break
          default:
            this.onResolvedCallbacks.push(() = > {
              setTimeout(() = > {
                try{
                  let x = onFulfilled(this.value)
                  resolvePromise(promise, x, resolve, reject)
                } catch(e){
                  reject(e)
                }
              })
            })
            this.onRejectedCallbacks.push(() = > {
              setTimeout(() = > {
                try{
                  let x = onRejected(this.reason)
                  resolvePromise(promise, x, resolve, reject)
                } catch(e){
                  reject(e)
                }
              })
            })
        }
    })
    return promise
  }
}

Promise.deferred = function(){
  let dfd = {}
  dfd.promise = new Promise((resolve,reject) = >{
      dfd.resolve = resolve;
      dfd.reject = reject;
  })
  return dfd;
}




module.exports = Promise

Copy the code

Add the test execution script

  • inpackage.jsonAdd the following script to
"scripts": {
    "test": "promises-aplus-tests index.js"
},
Copy the code
  • Input at terminalnpm run test

The final test passed with flying coloursPromise A+Standard, you can try

The next article continues with the introductionPromiseOther methods of

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, Master the implementation principle of the Promise (3) callback hell is what from zero rip Promise, master the implementation principle of the Promise (4) then method chain call preliminary implementation from zero rip Promise, Grasp the implementation principle of the Promise (5) then method chain call advanced implementation from zero rip Promise, grasp the implementation principle of the Promise (6) then method callback why is asynchronous microtask from zero rip Promise, Then method chain call the core method resolvePromise from zero hand tear Promise, Then method chain call core method resolvePromise to explore from zero hand tear Promise, Master the implementation principle of Promise (9)then method chain call of the core method resolvePromise complete from zero hand tear Promise, master the implementation principle of Promise (10)then method complete