preface

This article series is a compilation of notes from my training course.

With small white step by step to complete A+ specification Promise implementation, from shallow to deep.

Content parsing is very detailed, try to make each point why it is written so clearly annotated, some places even slightly wordy.

The average line of code A note, split into three versions 1.0, 2.0, 3.0, progressive layer by layer, the final 3.0 version will achieve Pomise/A+ specification. (Version 1.0 is guaranteed to be easy to understand)

As for why this article is divided into three, is afraid of many people and I see too long article collection first, and then eat ashes.

So, not lazy :). (Actually)

1.0 introduce myPromise

Readers familiar with Promise can look directly at the source code in the next section

Version 1.0 of myPromise will complete a promise that can handle synchronous states (asynchrony aside). Realized the promise of the following features, many daily use did not notice, but unconsciously in use.

1. The Promise constructor receives an executor function that executes immediately (that is, synchronously)

2. The executor function accepts two internal promise methods, resolve and Reject, which the consumer calls to change the promise into an appropriate state when appropriate

let mypromise = new Promise((resolve,reject) = > {
  // This arrow function is executor
})
Copy the code

3. Inside the executor function, exceptions are caught and reject is executed

let mypromise = new Promise((resolve,reject) = > {
  throw new Error('Throw exception')
  Reject (reject); reject (reject); reject (reject); reject (reject);
})
Copy the code

This is a big pity, which is a big pity. 4. There are three states (fulfilled,rejected failure,pending) and then method (the user can pass in the onFulfilled function and onRejected function).

let mypromise = new Promise((resolve,reject) = > {
  resolve('success')
})
mypromise.then((data) = > { / / onFulfilled function
  console.log('then resolve---',data);
},(err) = > { / / onRejected function
  console.log('then reject---',err);
})
// Note that the ondepressing function passed by the user in then and the resolve used by the user executor are both methods that will be called upon success. This can be considered as a pity.

//reject and onRejected
Copy the code

5. Promises are pending by default, and only when a promise is pending can the internal executor successfully call resolve or Reject and change the state.

let mypromise = new Promise((resolve,reject) = > {
  resolve('success')// Resolve internally changes the state from pending to resolve
  resolve('2' success)// There is no response for these three lines
  reject('failure')
  throw new Error('Throw exception')})Copy the code

1.0 source myPromise

After knowing the characteristics is to begin to realize, have to sigh big men’s wisdom.

Don’t say much, start code, words are in the comments.

/ / myPromise 1.0
const RESOLVED = 'RESOLVED'
const REJECTED = 'REJECTED'
const PENDING = 'PENDING'
console.log('my promise working');
class Promise {
  constructor(executor) {// The new Promise constructor is called immediately to receive the executor passed in by the user.
    this.status = PENDING;// Default wait state
    this.value = undefined;// It is used to store success data, which can be js, undefined, or promise
    this.reason = undefined;// For failure cause storage

    let resolve = (value) = > {// These two functions are not bound to this because they are not part of the instance and are passed in by the user
      if(this.status === PENDING) {// Only wait-state calls can change the state and execute resolve
        this.status = RESOLVED// When the user calls resolve, the state is set to 'resolve'.
        this.value = value// Step 2, save the success message}}let reject = (reason) = > {/ / same as above
      if(this.status === PENDING) {// This call is not executed when the state is resove or reject
        this.status = REJECTED
        this.reason = reason
      }
    }

    
    try {Trycatch is wrapped around an executor to catch run-time errors and throw new Error() when a non-user actively calls reject.
      executor(resolve,reject);// An executor is a function passed in by the executor user that executes immediately
      // And pass two functions to the actuator.
      Resolve is used when the user thinks success or wants to call the 'success' method or set the state to success, and a success message is passed
      // Call reject instead, passing in the cause of failure
    } catch (error) {// Assuming trycatch catches an error, reject is automatically called.
      reject(error)That is, reject is called whenever the user actively calls reject or when the promise executor runs wrong.}}// Above is the constructor that initializes the execution of the promise call, and below is the method that comes with the Promise class
  then(onFulfilled,onRejected) { // The consumer calls the Promise's then method, passing in the function to be called on success and the function to be called on failure
    if(this.status === RESOLVED) {// Then executes, deciding which function to call based on the state of the promise
      onFulfilled(this.value);
    }
    if(this.status === REJECTED) {
      onRejected(this.reason)
    }
  }
}

module.exports = Promise

That is, when the user calls a promise, the promise executes immediately and changes the state of the promise when the user calls then
// Pass in the methods to execute corresponding to the two states. Promise chooses to perform resolve or Reject, depending on the current state

Copy the code

Try at once

let Promise = require('./promise') // Introduce your own promise to experiment

let mypromise = new Promise((resolve,reject) = > {
  resolve('success')// Change state from Pending to resolve
  throw new Error('Throw exception')// The last two lines have no response
  reject('failure')
})
mypromise.then((data) = > {
  console.log('then resolve---',data);
},(err) = > {
  console.log('then reject---',err);
})
Copy the code

Finally output: My promise working then resolve– success

conclusion

It would be my greatest encouragement if I could help you. The code annotation version of 1.5 and 2.0 has been basically completed, and the markdown version will be sent out after it is written.

Next, version 1.5 will serve as a transition, and version 2.0 will solve the problem of asynchronous, chained calls.

MyPromise1.0 is actually a simple thing, but there are some bugs in it. Thank you for reading and pointing out.