前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【头条面试题】如何手写一个 Promise.all

【头条面试题】如何手写一个 Promise.all

作者头像
山月
发布2021-06-16 17:06:54
1.1K0
发布2021-06-16 17:06:54
举报

有一次头条面试,一道手写题目是:如何手写实现 promise.all

我从来没有想过要手写实现 promise.all 函数,稍微一想,大概就是维护一个数组,把所有 promise 给 resolve 了之后都扔进去,这有啥子好问的。没想到,一上手还稍微有点棘手。

先来看一个示例吧:

代码语言:javascript
复制
await Promise.all([1, Promise.resolve(2)])
//-> [1, 2]

await Promise.all([1, Promise.reject(2)])
//-> Throw Error: 2
  1. 传入一个 Iterable,但大部分情况下是数组,以下以数组代替
  2. 传入一个数组,其中可包含 Promise,也可包含普通数据
  3. 数组中 Prmise 并行执行
  4. 但凡有一个 Promise 被 Reject 掉,Promise.all 失败
  5. 保持输出数组位置与输入数组一致
  6. 所有数据 resolve 之后,返回结果
代码语言:javascript
复制
function pAll (_promises) {
  return new Promise((resolve, reject) => {
    // Iterable => Array
    const promises = Array.from(_promises)
    // 结果用一个数组维护
    const r = []
    const len = promises.length
    let count = 0
    for (let i = 0; i < len; i++) {
      // Promise.resolve 确保把所有数据都转化为 Promise
      Promise.resolve(promises[i]).then(o => { 
        // 因为 promise 是异步的,保持数组一一对应
        r[i] = o;

        // 如果数组中所有 promise 都完成,则返回结果数组
        if (++count === len) {
          resolve(r)
        }
        // 当发生异常时,直接 reject
      }).catch(e => reject(e))
    }
  })
}

为了测试,实现一个 sleep 函数

代码语言:javascript
复制
const sleep = (seconds) => new Promise(resolve => setTimeout(() => resolve(seconds), seconds))

以下示例进行测试,没有问题

代码语言:javascript
复制
pAll([1, 2, 3]).then(o => console.log(o))
pAll([
  sleep(3000),
  sleep(2000),
  sleep(1000)
]).then(o => console.log(o))
pAll([
  sleep(3000),
  sleep(2000),
  sleep(1000),
  Promise.reject(10000)
]).then(o => console.log(o)).catch(e => console.log(e, '<- Error'))
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-06-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 全栈成长之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档