1. A Promise is a class that when you execute that class you pass in an executor and that executor executes immediately
  2. There are three states in Promise: successful depressing failed waiting pending
Pending -> depressing pending -> Rejected Once the state is determined, it cannot be changedCopy the code
  1. The resolve and reject functions are used to change state
resolve: fulfilled
reject: rejected
Copy the code
  1. What the then method does internally is determine the state and if the state is a successful call to a successful callback and if the state is a failure call to a failed callback the then method is defined in the prototype object
  2. Then a successful callback takes one parameter to indicate the value after success. Then a failed callback takes one parameter to indicate the reason for failure
  3. The then methods under the same Promise object can be called multiple times
  4. The then method can be called chained. The callback of the later THEN method returns the value of the callback of the previous THEN method
const PENDING = 'pending'; / / wait for
const FULFILLED = 'fulfilled'; / / success
const REJECTED = 'rejected'; / / fail

class MyPromise {
  constructor (executor) {
    try {
      executor(this.resolve, this.reject)
    } catch (e) {
      this.reject(e); }}/ / promsie state
  status = PENDING;
  // Value after success
  value = undefined;
  // Cause of failure
  reason = undefined;
  // Successful callback
  successCallback = [];
  // Failed callback
  failCallback = [];

  resolve = value= > {
    // If the state is not waiting to prevent the program from executing down
    if (this.status ! == PENDING)return;
    // Change the status to success
    this.status = FULFILLED;
    // Save the value after success
    this.value = value;
    // Determine if the successful callback exists
    // this.successCallback && this.successCallback(this.value);
    while(this.successCallback.length) this.successCallback.shift()()
  }
  reject = reason= > {
    // If the state is not waiting to prevent the program from executing down
    if (this.status ! == PENDING)return;
    // Change the status to failed
    this.status = REJECTED;
    // Cause of save failure
    this.reason = reason;
    // Determine if the failed callback exists
    // this.failCallback && this.failCallback(this.reason);
    while(this.failCallback.length) this.failCallback.shift()()
  }
  then (successCallback, failCallback) {
    // Parameters are optional
    successCallback = successCallback ? successCallback : value= > value;
    // Parameters are optional
    failCallback = failCallback ? failCallback: reason= > { throw reason };
    let promsie2 = new MyPromise((resolve, reject) = > {
      // Determine the status
      if (this.status === FULFILLED) {
        setTimeout(() = > {
          try {
            let x = successCallback(this.value);
            // Determine whether x is a normal value or a promise object
            // Call resolve directly if it is a normal value
            // If it is a Promise object, look at the results returned by promsie
            // Call resolve or reject based on the result returned by the Promise object
            resolvePromise(promsie2, x, resolve, reject)
          }catch(e) { reject(e); }},0)}else if (this.status === REJECTED) {
        setTimeout(() = > {
          try {
            let x = failCallback(this.reason);
            // Determine whether x is a normal value or a promise object
            // Call resolve directly if it is a normal value
            // If it is a Promise object, look at the results returned by promsie
            // Call resolve or reject based on the result returned by the Promise object
            resolvePromise(promsie2, x, resolve, reject)
          }catch(e) { reject(e); }},0)}else {
        / / wait for
        // Store the success and failure callbacks
        this.successCallback.push(() = > {
          setTimeout(() = > {
            try {
              let x = successCallback(this.value);
              // Determine whether x is a normal value or a promise object
              // Call resolve directly if it is a normal value
              // If it is a Promise object, look at the results returned by promsie
              // Call resolve or reject based on the result returned by the Promise object
              resolvePromise(promsie2, x, resolve, reject)
            }catch(e) { reject(e); }},0)});this.failCallback.push(() = > {
          setTimeout(() = > {
            try {
              let x = failCallback(this.reason);
              // Determine whether x is a normal value or a promise object
              // Call resolve directly if it is a normal value
              // If it is a Promise object, look at the results returned by promsie
              // Call resolve or reject based on the result returned by the Promise object
              resolvePromise(promsie2, x, resolve, reject)
            }catch(e) { reject(e); }},0)}); }});return promsie2;
  }
  finally (callback) {
    return this.then(value= > {
      return MyPromise.resolve(callback()).then(() = > value);
    }, reason= > {
      return MyPromise.resolve(callback()).then(() = > { throw reason })
    })
  }
  catch (failCallback) {
    return this.then(undefined, failCallback)
  }
  static all (array) {
    let result = [];
    let index = 0;
    return new MyPromise((resolve, reject) = > {
      function addData (key, value) {
        result[key] = value;
        index++;
        if(index === array.length) { resolve(result); }}for (let i = 0; i < array.length; i++) {
        let current = array[i];
        if (current instanceof MyPromise) {
          / / promise object
          current.then(value= > addData(i, value), reason= > reject(reason))
        }else {
          / / common valuesaddData(i, array[i]); }}})}static resolve (value) {
    if (value instanceof MyPromise) return value;
    return new MyPromise(resolve= >resolve(value)); }}function resolvePromise (promsie2, x, resolve, reject) {
  if (promsie2 === x) {
    return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))}if (x instanceof MyPromise) {
    / / promise object
    // x.then(value => resolve(value), reason => reject(reason));
    x.then(resolve, reject);
  } else {
    / / common valuesresolve(x); }}module.exports = MyPromise;
Copy the code