手写Promise.all, Promise.race,Promise.finally方法

Promise.all():

/*
      参数:可迭代的数据类型,包括Array,Map, Set,例如[promise1, promise2, promise3...]
      返回值:一个promise对象
      规则:
          1.如果传入参数为空的可迭代对象,则返回一个已完成状态的promise
          2.等待所有完成或第一个失败
    */
    Promise.all = function (promises) {
      return new Promise((resolve, reject) => {
        // 1. 将promises转换为数组对象
        promises = Array.from(promises);
        // 空对象处理
        if (promises.length == 0) {
          return resolve([]);
        }
        let count = 0;
        let result = [];
        for (let i = 0; i < promises.length; i++) {
          // 考虑到参数可能不是promise对象的情况,
          // 使用promise.resolve将参数转化为promise对象,再使用.then方法进行处理
          Promise.resolve(promises[i]).then(data => {
            // 保存参数
            result[i] = data;
            count++;
            if (count== promises.length) {
              // 改变返回Promise对象的状态,批量处理result
              // 所有的promise状态都是fulfilled,promise.all返回的实例才变成fulfilled状态
              resolve(result);
            }
          }, err => {
            reject(err);
            return;
          })
        }
      });
    }
    // 测试1:
    const promise1 = Promise.resolve(3);
      const promise2 = 42;
      const promise3 = new Promise((resolve, reject) => {
        setTimeout(resolve, 100, 'foo');
      });

      Promise.all([promise1, promise2, promise3]).then((values) => {
        console.log(values);//[3, 42, "foo"]
      });

    // 测试2:
    const promise4 = Promise.resolve(3);
      const promise5 = Promise.reject(42);
      const promise6 = new Promise((resolve, reject) => {
        setTimeout(resolve, 100, 'bar');
      });

      Promise.all([promise4, promise5, promise6]).then(values => {
        console.log(values);
      }, reason => {
        console.log(reason)// 42
      });

Promise.race():

    // race先到先得(相比all)
    Promise.race = function (promises) {
      return new Promise((resolve, rejected) => {
        // 将参数转化为数组对象
        promises = Array.from(promises);
        if (promises.length == 0)
          return resolve([]);

        for (let i = 0; i < promises.length; i++) {
          // 解决参数不是promise的情况
          Promise.resolve(promises[i]).then(data => {
            resolve(data);
            return;
          }, err => {
            reject(err);
            return;
          })
        }
      })
    }

    // 测试
    const promise1 = new Promise((resolve, reject) => {
      setTimeout(resolve, 500, 'one');
    });

    const promise2 = new Promise((resolve, reject) => {
      setTimeout(resolve, 100, 'two');
    });

    Promise.race([promise1, promise2]).then((value) => {
      console.log(value);
      // Both resolve, but promise2 is faster
    });
// expected output: "two"

Promise.finally():

/*在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数
      finally() 虽然与 .then(onFinally, onFinally) 类似,它们不同的是:
      调用内联函数时,不需要多次声明该函数或为该函数创建一个变量保存它。
      由于无法知道promise的最终状态,所以finally的回调函数中不接收任何参数,
      它仅用于无论最终结果如何都要执行的情况。
      与Promise.resolve(2).then(() => {}, () => {}) (resolved的结果为undefined)不同,
      Promise.resolve(2).finally(() => {}) resolved的结果为 2。
      同样,Promise.reject(3).then(() => {}, () => {}) (fulfilled的结果为undefined),
      Promise.reject(3).finally(() => {}) rejected 的结果为 3。
    */

    // 调用对象:Promise.resolve(XXX),故使用this.then方法处理
    // 不管成功还是失败,都会走到finally中,并且finally之后,还可以继续then。并且会将值原封不动的传递给后面的then
    Promise.finally = function (callback) {
      return this.then(data => {
        return Promise.resolve(callback()).then(value => {
          return value;
        })
      }, err => {
        return Promise.reject(callback()).then(err => {
          throw err;
        })
      })
    }

    // 测试:
    function callback() {
      console.log('p='+false);
    }
    const p1 = Promise.resolve(123);
    p1.finally(callback)// p=false

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值