【每日一题NO.53】手写Promise.allSettled
人生苦短,总需要一点仪式感。比如学前端~
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
你也可以点击文末的 “阅读原文” 快速跳转
评论