promise.all是怎实现的?

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

目录
相关文章
|
7天前
|
前端开发 JavaScript
掌握 Promise.all:优雅处理多个异步操作
掌握 Promise.all:优雅处理多个异步操作
|
8天前
|
前端开发 JavaScript API
停止在 JavaScript 中使用 Promise.all()
停止在 JavaScript 中使用 Promise.all()
38 0
|
8月前
|
前端开发 API 数据库
Promise.all API 的出错处理
Promise.all API 的出错处理
37 0
|
9月前
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
62 0
前端学习案例24-promise.all和promise.race之2
|
前端开发
前端学习案例23-promise.all和promise.race
前端学习案例23-promise.all和promise.race
53 0
前端学习案例23-promise.all和promise.race
|
前端开发
前端学习案例1-promise之promise.all
前端学习案例1-promise之promise.all
53 0
前端学习案例1-promise之promise.all
|
前端开发 JavaScript
Promise.all等待所有Promise执行完成
Promise.all等待所有Promise执行完成
345 0
|
前端开发
Promise.all和promise.race的应用场景举例
Promise.all和promise.race的应用场景举例
160 0