【每日一题NO.53】手写Promise.allSettled

前端印记

共 1928字,需浏览 4分钟

 ·

2021-10-12 11:56

人生苦短,总需要一点仪式感。比如学前端~

Promise.allSettled MDN

概念

  • Promise.allSettled()方法接收一组 Promise 实例作为参数,返回一个新的 Promise 实例
  • 只有等到所有的这些参数实例都返回结果,不管是 fulfilled 还是 rejected,包装实例才会结束
  • 返回新的 Promise 实例,一旦结束,状态总是 fulfilled,不会变成 rejected
  • 新的 promise 实例给监听函数传递一个数组 results。该数组的每个成员都是一个对象,对应传入Promise.allSettled的Promise实例。每个对象都有status属性,对应着fulfilled和rejected。fulfilled时,对象有value属性,rejected时有reason属性,对应两种状态的返回值

有时候我们不关心异步操作的结果,只会关心这些操作有没有结束的时候,这时候比较适用Promise.allSettled()

使用

const resolved = Promise.resolve(42);
const rejected = Promise.reject(-1);

const allSettledPromise = Promise.allSettled([resolved, rejected]);

allSettledPromise.then(function (results{
  console.log(results);
});
// [
//    { status: 'fulfilled', value: 42 },
//    { status: 'rejected', reason: -1 }
// ]

简单实现

const formatSettledResult = (success, value) =>
  success
    ? { status"fulfilled", value }
    : { status"rejected"reason: value };

Promise.all_settled = function (iterators{
  const promises = Array.from(iterators);
  const num = promises.length;
  const resultList = new Array(num);
  let resultNum = 0;

  return new Promise((resolve) => {
    promises.forEach((promise, index) => {
      Promise.resolve(promise)
        .then((value) => {
          resultList[index] = formatSettledResult(true, value);
          if (++resultNum === num) {
            resolve(resultList);
          }
        })
        .catch((error) => {
          resultList[index] = formatSettledResult(false, error);
          if (++resultNum === num) {
            resolve(resultList);
          }
        });
    });
  });
};

// 测试
const resolved = Promise.resolve(42);
const rejected = Promise.reject(-1);
Promise.all_settled([resolved, rejected]).then((results) => {
  console.log(results);
});


所有《每日一题》的 知识大纲索引脑图 整理在此:https://www.yuque.com/dfe_evernote/interview/everyday
你也可以点击文末的 “阅读原文” 快速跳转


END
愿你历尽千帆,归来仍是少年。
浏览 31
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报