Skip to content

Promise(三):拓展方法实现

上次把 Promise 简单的实现了基本功能,趁热打铁,我们来实现一下它里面的拓展方法。

myPromise.prototype.catch

javascript
myPromise.prototype.catch = function (rejectFun) {
  return this.then(null, rejectFun);
};

catch 方法实现起来还是简单的,通过调用 Promise 的 then 方法,只传入失败的回调;then 方法会把值传递下去。


myPromise.prototype.finally

不管成功还是失败,都会执行

javascript
myPromise.prototype.finally = function (finallyFun) {
  return this.then((res) => {
    finallyFun();
    return res;
  }).catch((err) => {
    fiinallyFun();
    return err;
  });
};

myPromise.resolve

返回一个成功的 Promise

javascript
myPromise.resolve = function (res) {
  return new myPromise((resolve) => {
    resolve(res);
  });
};

myPromise.reject

返回一个失败的 Promise

javascript
myPromise.reject = function (res) {
  return new myPromise((resolve, reject) => {
    reject(res);
  });
};

myPromise.all

  • 返回一个 Promsie 实例,接收一个可迭代的对象,返回值是一个数组
  • 等参数内的值都执行成功才返回成功,只要有一个值返回失败,则返回失败
javascript
myPromise.all = function (arr) {
  /*判断参数类型*/
  if (!Array.isArray(arr)) {
    return new TypeError("参数类型错误,必须是数组");
  }
  let resolve;
  let reject;
  const promise = new myPromise((r, j) => {
    resolve = r;
    reject = j;
  });

  let fufilledCount = 0;
  let index = 0;
  const result = [];
  /*记录当前遍历的index*/
  const wrapFufilled = (i) => {
    return (val) => {
      fufilledCount += 1;
      result[i] = val;
      if (fufilledCount >= index) {
        resolve(result);
      }
    };
  };
  const wrapRejected = (i) => {
    return (err) => {
      reject(err);
    };
  };

  for (let item of arr) {
    myPromise.resolve(item).then(wrapFufilled(index), wrapRejected(index));
    index += 1;
  }
  return promise;
};

调用一下 myPromise.all

javascript
// 测试
const pro1 = new myPromise((res, rej) => {
  setTimeout(() => {
    res("1");
  }, 1000);
});
const pro2 = new myPromise((res, rej) => {
  setTimeout(() => {
    // res('2')
    rej("错误");
  }, 2000);
});
const pro3 = new myPromise((res, rej) => {
  setTimeout(() => {
    res("3");
  }, 3000);
});

const proAll = myPromise
  .all([pro1, pro2, pro3])
  .then(
    (res) => console.log(res) // 3秒之后打印 ["1", "2", "3"]
  )
  .catch((e) => {
    console.log(e); // “错误”
  });

其中一个失败时

总结: 1、Promise.all()接受一个 Array 类型的参数 2、只有数组中全部的 Promise 都变为 resolve 的时候 3、返回一个新的 Promise 实例 4、只要有一个失败,状态就变成 rejected


myPromise.race

返回一个 Promsie,接收一个数组作为参数,一旦数组其中一项执行,就返回执行结果。

javascript
myPromise.race = function (arr) {
  let resolve;
  let reject;
  const promise = new myPromsie((r, j) => {
    resolve = r;
    reject = j;
  });

  for (let item of arr) {
    myPromise.resolve(item).then(
      (val) => resolve(val),
      (err) => reject(err)
    );
  }
  return promise;
};

myPromise.any

只要其中一个 Promsie 成功,就返回成功的那个;如果没有一个成功,就返回失败,把失败的错误集中在一起。

javascript
myPromise.any = function (arr) {
  let resolve;
  let reject;
  const promise = new myPromise((r, j) => {
    resolve = r;
    reject = j;
  });

  let errCount = 0;
  let arrCount = 0;
  for (let item of arr) {
    arrCount += 1;
    myPromise.resolve(item).then(
      (val) => resolve(val),
      (err) => {
        errCount += 1;
        if (errCount >= arrCount) {
          reject(new AggregateError("所有Promsie都失败"));
        }
      }
    );
  }
  return promise;
};