With a promise to achieve js

/*
      Custom promise
        1. Perform MyPromise constructor to be executed immediately executor
        2. promise instance of an object, the internal state of the three
          Initialization pending
          Successfully resolved
          Failed rejected
          Note: The status can only be modified once
              If the internal executor wrong, promise to change the status rejected
        3. then implement methods
          promise.then(onResolved, onRejected)      
            promise of status is resolved, asynchronous function call onResolved
            promise of status is rejected, asynchronous function call onRejected
            promise of state is pending, the function is not called.
              Future promise may change, at this time or asynchronously call the appropriate function
        4. promise.then().then()  
          then method returns a value promise, chained to call
          Returns status value promise object:
            1. If no internal return value / return value is not a promise that is resolved
            2. If the internal state of the return value is the promise of promise see
            3. If the internal throw an exception, is rejected    
    */

    function MyPromise(executor) {
      // Initialize the promise instance object state
      this._status = 'pending';
      // initialize result value promise instance object
      this._value = undefined;

      // initialize the storage container callback function
      this._callbacks = {};

      // cache this -> promise instance of an object
      const _that = this;

      try {
        // error code may be placed
        // Once inside the code wrong try, try running it will break the code, directly to the catch
        // Perform MyPromise constructor to be executed immediately executor
        executor(resolve, reject);
      } catch (e) {
        // to catch, description of the internal function executor wrong ~
        // The promise object status change rejected
        reject(e);
      }

      // Define resolve
      function resolve(value) {
        // status can only be modified once
        if (_that._status === 'pending') {
          // call the method will resolve objects promise to change the state status resolved
          _that._status = 'resolved';
          _that._value = value;
          // function asynchronous call onResolved
          if (_that._callbacks.onResolved) {
            setTimeout(() => {
              _that._callbacks.onResolved(value)
            })
          }
        }
      }

      // define reject
      function reject(reason) {
        if (_that._status === 'pending') {
          // Call reject method will promise to change the object state rejected state
          _that._status = 'rejected';
          _that._value = reason;
          // function asynchronous call onRejected
          if (_that._callbacks.onRejected) {
            setTimeout(() => {
              _that._callbacks.onRejected(reason)
            })
          }
        }
      }
    }

    MyPromise.prototype.then = function (onResolved, onRejected) {
      const _that = this;

      // If onResolved exist, unchanged
      // If onResolved does not exist, explained catch trigger. If it is successful state promise, guarantee a successful return value or state promise
      onResolved = onResolved ? onResolved : (value) => value;
      // then pass a parameter only once method, and a failure state promise, guarantee that the returned value is the value of the internal state of the failed promise
      onRejected = onRejected ? onRejected : (reason) => {
        throw reason
      };

      // promise as a target for future use
      let promise = null;
      // this point to promise instance of an object
      if (this._status === 'resolved') {
        // Description promise object status is resolved
        // function asynchronous call onResolved
        promise = new MyPromise(function (resolve, reject) {
          setTimeout(() => {
            doResolve(onResolved, _that._value, resolve, reject);
          })
        })
      } else if (this._status === 'rejected') {
        promise = new MyPromise(function (resolve, reject) {
          setTimeout(() => {
            doResolve(onRejected, _that._value, resolve, reject);
          })
        })
      } else {
        // Description promise object's state is pending state
        // callback function exists on this
        promise = new MyPromise(function (resolve, reject) {
          // _that is p1, p2 is outside promise
          When // p1 call onResolved / onRejected callback to update status of p2
          _that._callbacks.onResolved = function (value) {
            doResolve(onResolved, value, resolve, reject);
          };
          _that._callbacks.onRejected = function (reason) {
            doResolve(onRejected, reason, resolve, reject);
          };
        })
      }
      // To call chain
      return promise;
    }

    // defined function code reuse
    function doResolve(onFn, value, resolve, reject) {
      try {
        const result = onFn(value);
        if (result instanceof MyPromise) {
          result.then(resolve, reject)
        } else {
          resolve(result);
        }
      } catch (e) {
        reject(e);
      }
    }

    MyPromise.prototype.catch = function (onRejected) {
      return this.then(undefined, onRejected);
    }

    MyPromise.prototype.finally = function (onResolved) {
      const _that = this;
      return new Promise((resolve, reject) => {
        if (_that._status === 'pending') {
          const callback = function (value) {
            doResolve(onResolved, value, resolve, reject)
          };
          _that._callbacks.onResolved = callback;
          _that._callbacks.onRejected = callback;
        } else {
          doResolve(onResolved, _that._value, resolve, reject);
        }
      })
    }

    // return a successful state promise
    MyPromise.resolve = function (value) {
      return new MyPromise((resolve, reject) => {
        resolve(value);
      })
    }
    // returns a failed state promise
    MyPromise.reject = function (reason) {
      return new MyPromise((resolve, reject) => {
        reject(reason);
      })
    }
    // accepts an array (promise of n objects placed in the array), only if all the objects are to promise success status, the method is the success return value promise
    // As long as there is a failure, the method returns the value of the promise will fail
    MyPromise.all = function (promises) {
      // promises of length
      const promiseLength = promises.length;
      // define identification variables: the number of objects promise of success
      let resolvedCount = 0;
      // successful outcome value
      const resolvedValues = [];
      return new MyPromise((resolve, reject) => {
        for (let i = 0; i < promiseLength; i++) {
          const promise = promises[i];
          // look at the state of promise
          promise.then((value) => {
            resolvedCount++;
            // will not mess with the push, the output order
            // use the index, in order to ensure order ok
            resolvedValues[i] = value;
            if (resolvedCount === promiseLength) {
              // explanation had been successful
              resolve(resolvedValues);
            }
          }, reject)
        }
      })
    }

    const promise = new MyPromise((resolve, reject) => {
      console.log ( 'executor function performs ~');
      setTimeout(() => {
        // resolve(111);
        reject(222);
      }, 2000)
    })

    promise
      .then(() => {
        console.log(111);
        // When the method is not passed then the second callback.
        // then the state of accepting the promise of the object is a failed state, the return value is a failed state
      })
      .catch((reason) => {
        console.log(222, reason);
        // return Promise.reject();
        // throw new Error(111)
        return 333;
      })
      .then((value) => {
        console.log(333, value);
      })
      .catch(() => {
        console.log(444);
      })

Guess you like

Origin www.cnblogs.com/wangsai-666/p/12038399.html