Write the source code

// State of the promise
const PENDING = 'pending'; / / wait for
const FULFILLED = 'fulfilled'; / / success
const REJECTED = 'rejected'; / / fail

class MyPromise {
  constructor(executor) {
    try {
      execcutor(this.resolve, this,reject)
    } catch(e) {
      console.log(e); }}/ / promsie state
  status = PENDING;

  // Value after success
  value = undefined;

  // The cause of the failure
  reason = undefined;

  // The storage callback succeeded
  successCallback = [];

  // Storage failed callback
  failCallback = [];

  resolve = value= > {
    // Stop the program from continuing if the current transition is not waiting
    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
    // We do not know the length of the successful callback array, so we use the while loop
    while (this.successCallback.length) {
      // Remove the first value with shift() and return the value
      const callback = this.successCallback.shift();

      The value returned is a function
      callback();
    }
  }

  reject = reason= > {
    // Stop the program from continuing if the current transition is not waiting
    if (this.status ! == PENDING)return;
    
    // Change the status to failed
    this. status = REJECTED;

    // The cause of the save failure
    this.reason = reason;

    // Determine if the successful callback exists
    // We do not know the length of the successful callback array, so we use the while loop
    while (this.failCallback.length) {
      // Remove the first value with shift() and return the value
      const callback = this.failCallback.shift();

      The value returned is a functioncallback(); }}/ / then method
  then(successCallback, failCallback) {

    // Parameters are optional
    successCallback = successCallback ? successCallback : value= > value;
    // Parameters are optional
    failCallback = failCallback ? failCallback: reason= > { throw reason };
    
    let promise2 = new MyPromise((resolve, reject) = > {
        // Determine the status
        if (this.status === FULFILLED) {
          // Success status
          setTimeout(() = > {
            try {
              let x = successCallback(this.value);

              // The next step is to determine whether it is a normal value or a promise
              resolvePromise(promise2, x, resolve, reject);
            } catch(e) { reject(e); }})}else if (this.status === REJECTED) {
          // Failed state
          setTimeout(() = > {
            try {
              let x = failCallback(this.reason);

              // The next step is to determine whether it is a normal value or a promise
              resolvePromise(promise2, x, resolve, reject);
            } catch(e) { reject(e); }})}else {
          / / wait for
          // Store the success and failure callbacks
          this.successCallback.push(() = > {
            setTimeout(() = > {
              try {
                let x = successCallback(this.value);
  
                // The next step is to determine whether it is a normal value or a promise
                resolvePromise(promise2, x, resolve, reject);
              } catch(e) { reject(e); }})})this.failCallback.push(() = > {
            setTimeout(() = > {
              try {
                let x = failCallback(this.reason);

                // The next step is to determine whether it is a normal value or a promise
                resolvePromise(promise2, x, resolve, reject);
              } catch(e) { reject(e); }})})return promsie2;
  }

  // Execute the finally method on failure or success
  finally (callback) {
    return this.then(value= > {
      return MyPromise.resolve(callback()).then(() = > value)
    },reason= > {
      return MyPromise.resolve(callback()).then(() = > { throw reason })
    });
  }

  // Error message catch method
  catch (failCallback) {
    return this.then(undefined, failCallback)
  }

  // Use the static all method
  static all (array) {
    let result = []; // Cache the return value of each async
    let index = 0; // Record the execution value of arR

    // Return a new promise
    return new MyPromise((resolve, reject) = > {
      function addData (key, value) {
        result[key] = value;
        index++;

        // Record the value and the length of the array
        if(index === array.length) { resolve(result); }}// Call the array one by one
      for (let i = 0; i < array.length; i++) {
        let current = array[i];
        
        // Determine whether it is a normal value or a promise value
        if (current instanceof MyPromise) {
          / / promise object
          current.then(value= > addData(i, value), reason= > reject(reason))
        }else {
          / / common valuesaddData(i, array[i]); }}})}// Use the static resolve method
  static resolve (value) {
    if (value instanceof MyPromise) return value;
    return new MyPromise(resolve= >resolve(value)); }}/ * * * *@param  Promise2 A newly created promise@param  X executes the return * of resolve or reject@param  Resolve Resolve * of promise2@param  Reject Reject */ of promise2

function resolvePromise(promise2, x, resolve, reject) {
  if(promise2 === x) {
    return reject(new TypeError('Promise returns itself in an infinite loop.'))}// Determine whether it is a normal value or a promise object
  if(x instanceof MyPromise) {
    / / promise object
    x.then(value= > resolve(value), reason= > reject(reason))
  } else {
    // The normal value returns the value directly
    resolve(x)
  }
}

module.exports = MyPromise;
Copy the code