模拟实现Promise.all

模拟实现Promise.all

一、前言

Promise.all 是es2015的Promise内置的一个静态方法,接受一个promises 数组,返回一个新的promise:

  1. 如果promises 数组的每一项的状态都变为fulfilled ,将返回的每一个promise 的结果按照原来数组的顺序,封装为一个新的数组作为成功的结果。
  2. 如果其中一个promise 的状态变为rejected, 就返回该promise

二、准备测试数据

javascript 复制代码
const promisesSuccess = []; // 五个成功的promise 数组
const promises = []; // 随机的promise
​
for (let i = 0; i < 5; i++) {
    // 成功的promise
    promisesSuccess.push(
        new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve(`${i * 1000}--resolve`);
            }, i * 1000);
        })
    );
    // 随机promise
    Math.random() > 0.1
        ? promises.push(
            new Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve(`${i * 1000}--resolve`);
                }, i * 1000);
            })
        )
        : promises.push(
            new Promise((resolve, reject) => {
                setTimeout(() => {
                    reject(`${i * 1000}--reject`);
                }, i * 1000);
            })
        );
}

三、实现Promise.all

1. 乞丐版:

javascript 复制代码
Promise.myAll = (promises) => {
    const arr = [];
    return new Promise((resolve, reject) => {
        promises.forEach((item, index) => {
            Promise.resolve(item).then((res) => {
                arr.push(res);
                if (arr.length === promises.length) resolve(arr);
            }, (reason)=>{
                reject(reason)
            });
        });
    });
};

乞丐版存在的问题:

  1. 返回的数组没有按照原本的顺序,而是按照peomise 完成的顺序加入数组
  2. 错误可以简写。

注意: 如果不额外定义一个length ,代码如下:

ini 复制代码
Promise.myAll = (promiseArr) => {
    const arr = [];
    return new Promise((resolve, reject) => {
        promises.forEach((item, index) => {
            Promise.resolve(item).then((res) => {
                arr[index] = res;
                if (arr.length === promises.length) resolve(arr);
            }, reject);
        });
    });
};

分析: 如果promiseArr 数组的 的最后一项先完成,此时的arr为[empty,empty,...,empty, res],显然此时的arr.length === promiseArr.length 成立,导致出错。

2. 完整版

ini 复制代码
Promise.myAll = (promiseArr) => {
    const arr = [];
    let count = 0;
    return new Promise((resolve, reject) => {
        promises.forEach((item, index) => {
            Promise.resolve(item).then((res) => {
                arr[index] = res;
                count += 1; 
                if (count === promises.length) resolve(arr);
            }, reject);
        });
    });
};

四、 测试

javascript 复制代码
Promise.myAll(promisesSuccess).then(
    (res) => {
        console.log(res);
    },
    (reason) => {
        console.log(reason);
    }
);
​
Promise.myAll(promises).then(
    (res) => {
        console.log(res);
    },
    (reason) => {
        console.log(reason);
    }
);

执行结果:

相关推荐
StarPrayers.13 分钟前
旅行商问题(TSP)(2)(heuristics.py)(TSP 的两种贪心启发式算法实现)
前端·人工智能·python·算法·pycharm·启发式算法
一壶浊酒..30 分钟前
ajax局部更新
前端·ajax·okhttp
DoraBigHead1 小时前
React 架构重生记:从递归地狱到时间切片
前端·javascript·react.js
彩旗工作室2 小时前
WordPress 本地开发环境完全指南:从零开始理解 Local by Flywhee
前端·wordpress·网站
iuuia2 小时前
02--CSS基础
前端·css
kyle~2 小时前
Qt---setAttribute设置控件或窗口的内部属性
服务器·前端·c++·qt
FIN66682 小时前
昂瑞微:射频与模拟芯片领域的国产领军者
前端·人工智能·科技·前端框架·智能
苦夏木禾2 小时前
css实现表格中最后一列固定
前端·javascript·css
LuHang3 小时前
WebSocket服务封装实践:从连接管理到业务功能集成
前端·websocket