promise.all是怎实现的?

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: promise.all是怎实现的?

说在前面

🎈promise.all()大家都用过吗?今天来仿写一个promise.all

题目描述

给定一个异步函数数组 functions,返回一个新的 promise 对象 promise。数组中的每个函数都不接受参数并返回一个 promise。所有的 promise 都应该并行执行。

promise resolve 条件:

  • 当所有从 functions 返回的 promise 都成功的并行解析时。promise 的解析值应该是一个按照它们在 functions 中的顺序排列的 promise 的解析值数组。promise 应该在数组中的所有异步函数并行执行完成时解析。

promise reject 条件:

  • 当任何从 functions 返回的 promise 被拒绝时。promise 也会被拒绝,并返回第一个拒绝的原因。

请在不使用内置的 Promise.all 函数的情况下解决。

示例 1:

输入: functions = [
  () => new Promise(resolve => setTimeout(() => resolve(5), 200))
]
输出: {"t": 200, "resolved": [5]}
解释:
promiseAll(functions).then(console.log); // [5]
单个函数在 200 毫秒后以值 5 成功解析。

示例 2:

输入: functions = [
    () => new Promise(resolve => setTimeout(() => resolve(1), 200)), 
    () => new Promise((resolve, reject) => setTimeout(() => reject("Error"), 100))
]
输出: {"t": 100, "rejected": "Error"}
解释: 由于其中一个 promise 被拒绝,返回的 promise 也在同一时间被拒绝并返回相同的错误。

示例 3:

输入: functions = [
    () => new Promise(resolve => setTimeout(() => resolve(4), 50)), 
    () => new Promise(resolve => setTimeout(() => resolve(10), 150)), 
    () => new Promise(resolve => setTimeout(() => resolve(16), 100))
]
输出: {"t": 150, "resolved": [4, 10, 16]}
解释: 所有的 promise 都成功执行。当最后一个 promise 被解析时,返回的 promise 也被解析了。

提示:

  • 函数 functions 是一个返回 promise 的函数数组
  • 1 <= functions.length <= 10

解题思路

首先创建一个新的 Promise 对象,用于处理异步操作的结果。然后,函数创建了一个与传入的函数数量相同长度的空数组 res,用于存储每个函数执行的结果。同时,定义了一个计数器 cnt,用于记录已经执行完成的函数数量。

接下来,函数使用 forEach 方法对传入的函数数组进行迭代。在每次迭代中,函数调用当前函数 fn,并通过 .then() 方法注册一个回调函数来处理异步操作的结果。当异步操作成功完成时,回调函数会将结果存储在 res 数组的相应位置,并将计数器 cnt 增加 1。如果计数器 cnt 的值等于 res 数组的长度,表示所有函数都已经执行完成,则通过 resolve 方法将结果数组 res 作为 Promise 的最终结果返回。

如果在任何一个函数执行过程中出现错误,则通过 catch 方法将错误信息传递给 Promise 的 reject 方法,使 Promise 进入拒绝状态,并传递错误信息。

最后,通过调用 promiseAll 函数并传入一个包含一个异步操作的函数的数组,可以得到一个 Promise 对象,当异步操作成功完成时,该 Promise 对象会将结果数组 [42] 返回,并通过 .then() 方法中的回调函数进行处理。

AC代码

/**
 * @param {Array<Function>} functions
 * @return {Promise<any>}
 */
var promiseAll = function (functions) {
  return new Promise((resolve, reject) => {
    const res = new Array(functions.length);
    let cnt = 0;
    functions.forEach((fn, fnInd) => {
      fn()
        .then((response) => {
          res[fnInd] = response;
          cnt++;
          if (cnt === res.length) resolve(res);
        })
        .catch((err) => {
          reject(err);
        });
    });
  });
};
/**
 * const promise = promiseAll([() => new Promise(res => res(42))])
 * promise.then(console.log); // [42]
 */
const promise = promiseAll([() => new Promise((res) => res(42))]);
promise.then(console.log); // [42]

公众号

关注公众号『前端也能这么有趣』,获取更多有趣内容。

说在后面

🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,偶尔也会在自己的公众号『前端也能这么有趣』发一些比较有趣的文章,有兴趣的也可以关注下。在此谢谢大家的支持,我们下文再见 🙌。

目录
相关文章
|
13天前
|
前端开发 索引
Promise.all() 方法的参数可以是什么类型?
综上所述,`Promise.all()` 方法的参数类型较为灵活,但无论使用哪种类型的可迭代对象作为参数,其核心的异步操作处理逻辑和成功失败的判断机制都是一致的,都是为了方便地处理多个异步操作的并发执行和结果汇总。
|
8天前
|
前端开发
`Promise.allSettled()`方法与`Promise.all()`方法有何不同?
`Promise.allSettled()` 提供了一种更灵活和全面的方式来处理多个 `Promise`,使得我们能够更好地应对各种异步操作的情况,尤其是需要详细了解每个 `Promise` 结果的场景。
|
3天前
|
监控 调度
在什么情况下应该使用 Promise.allSettled() 方法?
总的来说,`Promise.allSettled()` 为我们处理多个异步任务提供了一种更灵活、更全面的方式,使我们能够更好地应对各种复杂的情况,确保在获取到所有任务结果的同时,能够进行更有效的后续处理和决策。
|
26天前
|
前端开发
使用 Promise.all 处理多个 Promise 同时失败的情况
【10月更文挑战第26天】通过以上几种方法,我们可以根据具体的需求和环境选择合适的方式来处理多个 `Promise` 同时失败的情况,从而更好地进行错误处理和程序的稳定性保障。
99 2
|
4月前
|
前端开发
手写实现ES6的Promise.all()和Promise.race()函数
这篇文章介绍了如何手写实现ES6的`Promise.all()`和`Promise.race()`函数,提供了实现这两个Promise聚合函数的详细代码示例,并展示了如何使用它们。
手写实现ES6的Promise.all()和Promise.race()函数
|
5月前
|
前端开发 JavaScript
js【详解】Promise(含 Promise 的三种状态及其变化,创建 Promise, Promise.all 语法、Promise.all 实战范例、手写 Promise.all)
js【详解】Promise(含 Promise 的三种状态及其变化,创建 Promise, Promise.all 语法、Promise.all 实战范例、手写 Promise.all)
611 0
|
7月前
|
前端开发 JavaScript
掌握 Promise.all:优雅处理多个异步操作
掌握 Promise.all:优雅处理多个异步操作
Promise.all和Promise.race的区别和使用
比如当数组里的P1,P2都执行完成时,页面才显示。 值得注意的是,返回的数组结果顺序不会改变,即使P2的返回要比P1的返回快,顺序依然是P1,P2 Promise.all成功返回成功数组, 失败返回失败数据,一但失败就不会继续往下走
|
前端开发
Promise.all()方方详解
Promise.all()方方详解
Promise.all()方方详解
|
前端开发
前端学习案例24-promise.all和promise.race之2
前端学习案例24-promise.all和promise.race之2
85 0
前端学习案例24-promise.all和promise.race之2