模拟实现Promise.all

模拟实现Promise.all

一、前言

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

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

二、准备测试数据

const promisesSuccess = []; // 五个成功的promise 数组
const promises = []; // 随机的promisefor (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. 乞丐版:

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 ,代码如下:

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. 完整版

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);
        });
    });
};

四、 测试

Promise.myAll(promisesSuccess).then(
    (res) => {
        console.log(res);
    },
    (reason) => {
        console.log(reason);
    }
);
​
Promise.myAll(promises).then(
    (res) => {
        console.log(res);
    },
    (reason) => {
        console.log(reason);
    }
);

执行结果:

模拟实现Promise.all

原文链接:https://juejin.cn/post/7355088718371930122 作者:Rock1688

(0)
上一篇 2024年4月8日 下午4:26
下一篇 2024年4月8日 下午4:36

相关推荐

发表回复

登录后才能评论