zoukankan      html  css  js  c++  java
  • 用js实现promise

    /*
          自定义promise
            1. 执行MyPromise构造函数,要立即执行executor
            2. promise实例对象,内部有三种状态
              初始化 pending
              成功 resolved
              失败 rejected
              注意:状态只能修改一次
                  如果executor内部出错了,promise状态改成rejected
            3. then方法的实现
              promise.then(onResolved, onRejected)      
                promise的状态是resolved时,异步调用onResolved函数
                promise的状态是rejected时,异步调用onRejected函数
                promise的状态是pending时,不调用函数。
                  未来promise可能会变化,此时还是要异步调用相应的函数
            4. promise.then().then()  
              then方法返回值是promise,才能链式调用
              返回值promise对象的状态:
                1. 如果内部没有返回值 / 返回值不是promise 就是resolved
                2. 如果内部返回值是promise 看promise的状态
                3. 如果内部抛异常,就是rejected    
        */

        function MyPromise(executor) {
          // 初始化promise实例对象状态
          this._status = 'pending';
          // 初始化promise实例对象结果值
          this._value = undefined;

          // 初始化存储 回调函数 的容器
          this._callbacks = {};

          // 缓存this --> promise实例对象
          const _that = this;

          try {
            // 放置可能出错代码
            // 一旦try里面代码出错了,就会中断try中代码运行,直接来到catch
            // 执行MyPromise构造函数,要立即执行executor
            executor(resolve, reject);
          } catch (e) {
            // 来到catch,说明executor函数内部出错了~
            // 将promise对象状态改成rejected
            reject(e);
          }

          // 定义resolve
          function resolve(value) {
            // 状态只能修改一次
            if (_that._status === 'pending') {
              // 调用resolve方法将promise对象状态改成resolved状态
              _that._status = 'resolved';
              _that._value = value;
              // 异步调用onResolved函数
              if (_that._callbacks.onResolved) {
                setTimeout(() => {
                  _that._callbacks.onResolved(value)
                })
              }
            }
          }

          // 定义reject
          function reject(reason) {
            if (_that._status === 'pending') {
              // 调用reject方法将promise对象状态改成rejected状态
              _that._status = 'rejected';
              _that._value = reason;
              // 异步调用onRejected函数
              if (_that._callbacks.onRejected) {
                setTimeout(() => {
                  _that._callbacks.onRejected(reason)
                })
              }
            }
          }
        }

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

          // 如果onResolved存在,不变
          // 如果onResolved不存在,说明catch触发的。 如果是成功状态promise,保证返回值还是一个成功状态promise
          onResolved = onResolved ? onResolved : (value) => value;
          // then方法一旦只传一个参数,并且是失败状态promise,保证返回值 是 失败状态promise内部的值
          onRejected = onRejected ? onRejected : (reason) => {
            throw reason
          };

          // 为了将来作为promise对象使用
          let promise = null;
          // this指向promise实例对象
          if (this._status === 'resolved') {
            // 说明promise对象的状态是resolved
            // 异步调用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 {
            // 说明promise对象的状态是pending状态
            // 将回调函数存在this上
            promise = new MyPromise(function (resolve, reject) {
              // _that是p1, 外面promise是p2
              // p1调用onResolved/onRejected回调时,要更新p2的状态
              _that._callbacks.onResolved = function (value) {
                doResolve(onResolved, value, resolve, reject);
              };
              _that._callbacks.onRejected = function (reason) {
                doResolve(onRejected, reason, resolve, reject);
              };
            })
          }
          // 为了链式调用
          return promise;
        }

        // 定义函数复用代码
        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);
            }
          })
        }

        // 返回一个成功状态promise
        MyPromise.resolve = function (value) {
          return new MyPromise((resolve, reject) => {
            resolve(value);
          })
        }
        // 返回一个失败状态promise
        MyPromise.reject = function (reason) {
          return new MyPromise((resolve, reject) => {
            reject(reason);
          })
        }
        // 接受一个数组(数组中放置n个promise对象),只有所有promise对象都成成功状态,方法返回值的promise才是成功
        // 只要有一个失败,方法返回值的promise就失败
        MyPromise.all = function (promises) {
          // promises的长度
          const promiseLength = promises.length;
          // 定义标识变量: promise对象成功的数量
          let resolvedCount = 0;
          // 成功的结果值
          const resolvedValues = [];
          return new MyPromise((resolve, reject) => {
            for (let i = 0; i < promiseLength; i++) {
              const promise = promises[i];
              // 看promise的状态
              promise.then((value) => {
                resolvedCount++;
                // 不能用push,输出顺序会乱
                // 使用下标,才能保证顺序ok
                resolvedValues[i] = value;
                if (resolvedCount === promiseLength) {
                  // 说明都成功了
                  resolve(resolvedValues);
                }
              }, reject)
            }
          })
        }

        const promise = new MyPromise((resolve, reject) => {
          console.log('executor函数执行了~');
          setTimeout(() => {
            // resolve(111);
            reject(222);
          }, 2000)
        })

        promise
          .then(() => {
            console.log(111);
            // 当then方法没有传入第二个回调。
            // 那么一旦接受的promise对象的状态是失败状态,返回值也是失败状态
          })
          .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);
          })

  • 相关阅读:
    面向对象设计原则之二:开放封闭原则
    面向对象设计原则之一:单一职责原则
    设计模式之四:适配器模式(Adapter Pattern)
    面向对象设计原则之六:合成/聚合复用原则
    设计模式之三:迭代器模式(IteratorPattern)
    面向对象设计原则之五:迪米特法则
    设计模式之二:观察者模式(Observer Pattern)
    五分钟搭建 Flash 视频直播站
    Flash Media Server 3 开发版供下载
    不掉线的路由器路由特殊技术分析
  • 原文地址:https://www.cnblogs.com/wangsai-666/p/12038399.html
Copyright © 2011-2022 走看看