手动实现一个 Promise.all

发布于 2023-05-01 20:56:47 字数 1587 浏览 65 评论 0

MDN : Promise.all() 方法接收一个 promise 的 iterable 类型(注:Array,Map,Set 都属于 ES6 的 iterable 类型)的输入,并且只返回一个 Promise 实例,那个输入的所有 promise 的 resolve 回调的结果是一个数组。

这个Promise 的 resolve 回调执行是在所有输入的 promise 的 resolve 回调都结束,或者输入的 iterable 里没有 promise 了的时候。它的 reject 回调执行时,只要任何一个输入的 promise 的 reject 回调执行或者输入不合法的 promise 就会立即抛出错误,并且 reject 的是第一个抛出的错误信息。

Promise.all = function(arr) {
    return new Promise((resolve, reject) => {
        // 判断是否是可迭代对象
        if(typeof arr !== 'object' || arr === null || typeof arr[Symbol.iterator] !== 'function') {
            throw new Error('arr is not a iterable ')
        }
        // 转化为对象
        const promises = [...arr]

        if(promises.length === 0) {
            resolve([])
            return 
        }
        let count = 0
        const results = []
        promises.forEach((p,idx) => {
            Promise.resolve(p).then(res => {
                results[idx] = res
                count++
                if(count === promises.length) {
                    resolve(results)
                }
            }).catch(reject)
        })
    })
}

// test

Promise.all(1)

Promise.all([1,Promise.reject(2),Promise.resolve(3)])

Promise.all(new Set([1,2 ,Promise.resolve(true)]))

要点

  1. 注意传入参数的类型,必须为可迭代对象
  2. 对于每个值使用Promise.resolve 进行包裹,而不是判断值的类型在进行处理

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

软糖

暂无简介

0 文章
0 评论
24 人气
更多

推荐作者

wanghao

文章 0 评论 0

蓝天

文章 0 评论 0

handsomedeng

文章 0 评论 0

仙女

文章 0 评论 0

石海龙

文章 0 评论 0

dianjvnan

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文