Skip to content

手写 Promise.all

功能:并行执行一组 Promise,全部成功resolved,任意一个失败则立刻 rejected,并且保证返回结果的顺序与输入顺序一致。

思路

  • 遍历传入的可迭代对象 promises,为每一项包装 Promise.resolve
    • 这样即使输入中有普通值,也会被转成已完成的 Promise;
  • 使用 result[index] 按输入顺序存放每个 Promise 的结果;
  • fulfilled 记录已经成功的数量,当 fulfilled === count 时,整体 resolve(result)
  • 如果没有任何输入(count === 0),直接返回空数组。

代码

js
/**
 * Promise.all 完成并行任务,接收 promise 数组,返回一个 promise
 * 在所有输入的 Promise 都成功时才会 resolved,并返回一个包含所有结果的数组
 * 任何一个输入的 Promise 被拒绝,返回的 Promise 会立即被拒绝,并返回该拒绝的错误
 * 注意:Promise.all 输入输出顺序不会变
 * @param {iterator} promises
 */

Promise.myAll = function(promises) {
    return new Promise((res, rej) => {
        let count = 0;
        let fulfilled = 0;
        const result = [];
        for (const promise of promises) {
            const index = count;
            count++;
            // Promise.resolve() 用于将现有对象转为 Promise 对象,若已是 Promise 对象则原封不动返回
            Promise.resolve(promise).then((data) => {
                result[index] = data;
                fulfilled++;
                if (fulfilled === count) {
                    res(result);
                }
            }, rej);
        }
        if (count === 0) {
            res([]);
        }
    });
}