2021-11-29 手写PromiseA+

包含promise原型对象的方法:.then() 和 .catch();
promise对象上的方法: resolve() / reject() / all() / race() ;
自定义promise对象方法:
Promise.resolvedDelay(value, time) 规定时间成功
Promise.rejectedDalay(reason, time ) 规定时间失败

/*
  自定义Promise函数模块: IIFE
*/

(function (window) {

  const PENDING = 'pending';
  const RESOLVED = 'resolved';
  const REJECTED = 'rejected';

  /**
    * Promise构造函数
    * excutor: 执行器函数(同步执行)
   */
  function Promise(excutor) {

    // 将当前promise对象保存起来
    const that = this;
    that.status = PENDING; // 给promise对象指定status属性,初始值为PENDING
    that.data = undefined; // 给promise对象指定一个用于存出结果数据的属性
    that.callbacks = []; // 每个元素的结构: { onResolved() {},  onRejected() {} }

    function resolve(value) {
      // 如果当前状态不是PENDING,直接结束
      if (that.status !== PENDING) return;

      // 将状态改为RESOLVED
      that.status = RESOLVED;
      // 保存value数据
      that.data = value;
      // 如果有待执行callback函数,立即异步执行回调函数 onResolved
      if (that.callbacks.length > 0) {
        // 放入队列中执行所有成功的回调
        setTimeout(() => {
          that.callbacks.forEach(callbacksObj => {
            callbacksObj.onResolved(value);
          });
        });
      };

    };

    function reject(reason) {
      // 如果当前状态不是PENDING,直接结束
      if (that.status !== PENDING) return;

      // 将状态改为REJECTED
      that.status = REJECTED;
      // 保存value数据
      that.data = reason;
      // 如果有待执行的callback函数,立即异步执行回调函数onREJECTED
      if (that.callbacks.length > 0) {
        setTimeout(() => {
          that.callbacks.forEach((callbacksObj) => {
            callbacksObj.onRejected(reason);
          });
        });
      };
    };

    // 立即同步执行excutor 
    try {
      excutor(resolve, reject);
    } catch (error) {  // 如果执行器抛出异常,promise对象变为REJECTED状态
      reject(error);
    }
  };
  /* 
    Promise原型对象的then()
    指定成功和失败的回调函数
    返回一个新的promise对象
  */
  Promise.prototype.then = function (onResolved, onRejected) {
    // 指定两个回调函数的默认值(必须是函数)
    onResolved = typeof onResolved === 'function' ? onResolved : value => value;  // 向后传递成功的value
    // 指定默认的失败的回调(实现错误 / 异常穿透的关键点)
    onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };  // 向后传递失败的reason


    const that = this;
    // 返回一个新的promise对象
    return new Promise((resolve, reject) => {

      /* 
        调用指定回调函数处理, 根据执行结果,改变return的promise的状态。
      */
      function handle(callback) {
        /*
          1. 如果抛出异常,return的promise就会失败,reason 就是 error
          2. 如果回调函数返回的不是promise, return的promise就会是成功, value就是返回的值
          3. 如果回调函数返回的是promise, return的promise结果就是这个promise 的结果
        */
        try {
          const result = callback(that.data);
          if (result instanceof Promise) {
            result.then(resolve, reject);
          } else {
            resolve(result);
          }
        } catch (error) {
          reject(error);
        };
      }

      // 当前状态还是pending状态,将回调函数保存起来
      if (that.status === PENDING) {
        that.callbacks.push({
          onResolved() {
            handle(onResolved);
          },
          onRejected() {
            handle(onRejected);
          },
        });
      } else if (that.status === RESOLVED) {  // 如果当前是resolved状态,异步执行onResolved并改变return的promise状态
        setTimeout(() => {
          handle(onResolved);
        });
      } else {  //  如果当前是resolved状态,异步执行onRejected并改变return的promise状态。
        setTimeout(() => {
          handle(onRejected);
        });
      }
    })
  };
  /* 
    Promise原型对象的catch()
    指定失败的回调函数
    返回一个新的promise对象
  */
  Promise.prototype.catch = function (onRejected) {
    return this.then(undefined, onRejected);
  };

  /* 
    Promise函数对象的resolve方法
    返回一个指定结果的成功的promise
  */
  Promise.resolve = function (value) {
    // 返回一个成功的promise
    return new Promise((resolve, reject) => {

      if (value instanceof Promise) {
        // 是promise的话,使用value的结果作为promise的结果
        value.then(resolve, reject);
      } else {
        // promise变为成功,数据是value
        resolve(value);
      };
    });
  };

  /* 
    Promise函数的reject方法
    返回一个指定结果的失败的promise
  */
  Promise.reject = function (reason) {
    return new Promise((resolve, reject) => {
      reject(reason);
    });
  };

  /* 
    Promise函数的all方法
    返回一个promise, 只有当所有promise都成功时才成功,否则只要有一个失败的就失败
  */
  Promise.all = function (promiseArr) {
    const valuesArr = new Array(promiseArr.length); // 保存所有成功的value值
    let resolvedCount = 0;  // 用来保存成功的promise数量
    return new Promise((resolve, reject) => {
      // 遍历promise获取每个Promise的结果
      promiseArr.forEach((pObj, index) => {
        Promise.resolve(pObj).then(
          value => {
            // 当前的p成功,将成功的value放入数组中
            valuesArr[index] = value; // 注意顺序问题,按照promiseArr的顺序放入
            resolvedCount++;
            // 如果全部成功了,将return的promise改变成功
            if (resolvedCount === promiseArr.length) {
              resolve(valuesArr);
            };
          },
          reason => {  // 只要有一个失败了,return的promise就失败了
            reject(reason);
          }
        )
      })
    })
  };

  /* 
    Promise函数的race方法
    返回一个promise,其结果由第一个完成的promise决定,第一个失败就是失败,否则就是成功
  */
  Promise.race = function (promiseArr) {
    return new Promise((resolve, reject) => {
      // 遍历每个promise获取结果
      promiseArr.forEach((pObj, index) => {
        if (pObj instanceof Promise) {  // 可以判断pObj是不是promise,也可以 Promie.resolve(pObj).then()
          pObj.then(
            value => {  // 一旦有成功的,将return 变为成功
              resolve(value);
            },
            reason => {
              reject(reason);
            },
          );
        } else {
          resolve(pObj);
        };
      });
    });
  };


  /* 
    Promise函数对象上的 resolveDelay方法
    返回一个promise对象,它在指定的时间后才确定结果
  */
  Promise.resolveDelay = function (value, time) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        if (value instanceof Promise) {
          value.then(resolve, reject);
        } else {
          resolve(value);
        }
      }, time);
    });
  };

  /* 
    Promise函数对象上的 rejectDelay方法
    返回一个promise对象,它在指定的时间后才失败
  */
  Promise.rejectDelay = function (reason, time) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        reject(reason);
      }, time);
    });
  };

  // 向外暴露Promise函数
  window.Promise = Promise;
})(window);

测试代码:

    const p4 = new Promise((resolve) => {
      setTimeout(() => {
        resolve(4);
      }, 1000);
    });
    const p1 = Promise.resolve(1);
    const p3 = Promise.resolve(Promise.reject(3));
    const p5 = Promise.resolve(5);
    const p2 = Promise.reject(Promise.resolve(2));

    p4.then((value) => {
      console.log("p4", value);
    });
    p1.then((value) => console.log("p1", value));
    p2.catch((value) => console.log("p2", value));
    p3.catch((reason) => console.log("p3", reason));

    const pAll = Promise.all([p4, 2, p1, p5]);
    pAll.then(
      (values) => {
        console.log("pAll onResolved()", values);
      },
      (reason) => {
        console.log("pAll onRejected()", reason);
      }
    );
    const pRace = Promise.race([p1, p3, p2, p5, p4]);
    pRace.then(
      (value) => {
        console.log("pRace onResolved()", value);
      },
      (reason) => {
        console.log("pRace onRejected()", reason);
      }
    );

    const p6 = Promise.resolveDelay(66, 2000);
    const p7 = Promise.rejectDelay(77, 3000);
    p6.then((value) => console.log("p6", value));
    p7.catch((reason) => console.log("p7", reason));

撒花✿✿ヽ(°▽°)ノ✿

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容