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

目录
相关文章
|
移动开发 编解码 前端开发
【面试题】前端 移动端自适应?
【面试题】前端 移动端自适应?
488 0
|
前端开发 搜索推荐 UED
解密前端路由: hash模式vs.history模式
解密前端路由: hash模式vs.history模式
|
22天前
|
Kubernetes 安全 应用服务中间件
Kubernetes 官方再出公告,强调立即迁移 Ingress NGINX
北京时间 1 月 30 日,Kubernetes 指导委员会和安全响应委员会在 kubernetes.io 再次发出公告《Ingress NGINX: Statement from the Kubernetes Steering and Security Response Committees》,并通过 CNCF 官方微信公众号发布中文版公告。
136 20
|
10月前
|
Linux iOS开发 Docker
MyEMS开源系统安装之Linux/macOS上的DOcker
本指南详细介绍了如何在Linux/macOS上使用Docker部署MyEMS系统。主要内容包括:前置条件(如安装Docker、npm和MySQL),以及分步骤部署各个组件(如myems-api、myems-admin、myems-modbus-tcp等)。每个步骤涵盖源代码复制、环境配置、镜像构建、容器运行及日志管理等操作,并提供了多平台构建的支持。最后,指南还说明了默认端口和登录凭据,帮助用户快速启动并访问MyEMS的管理界面和Web界面。
357 1
|
人工智能 自然语言处理 安全
已解决:国内如何使用Claude 3.5 Sonnet \ claude官网中文入口
已解决:国内如何使用Claude 3.5 Sonnet \ claude官网中文入口
3036 20
|
人工智能 自然语言处理 算法
Devika AI:开源的 AI 软件开发工具,理解和执行复杂的人类指令
Devika AI 是一款开源的 AI 软件开发工具,能够理解和执行复杂的人类指令。它通过分解任务、信息搜集和代码生成,帮助开发者提高效率,减少人工干预。本文将详细介绍 Devika AI 的功能、技术原理以及如何运行和配置该工具。
725 9
Devika AI:开源的 AI 软件开发工具,理解和执行复杂的人类指令
|
Java Linux Maven
Autogen4j: the Java version of Microsoft AutoGen
Java version of Microsoft AutoGen, Enable Next-Gen Large Language Model Applications
|
网络协议 API 网络安全
Web实时通信的学习之旅:轮询、WebSocket、SSE的区别以及优缺点
Web实时通信的学习之旅:轮询、WebSocket、SSE的区别以及优缺点
3016 0
|
前端开发 JavaScript 数据挖掘
合成养成类游戏开发技术规则
合成养成类游戏结合了养成与合成的元素,提供策略性和趣味性的体验。开发涉及游戏设计、技术选型、开发测试、用户体验和合规安全等多方面规则,确保游戏品质、安全性和用户体验。通过合理的技术选型和精心设计,可以开发出具有市场竞争力的游戏产品。
|
缓存 前端开发 JavaScript
前端性能优化都有那些方案 ?
【7月更文挑战第11天】 前端性能优化包括资源合并压缩、懒加载、CDN使用、代码优化、缓存利用和图片优化等策略。例如,减少HTTP请求、压缩CSS/JS、事件委托、利用浏览器及服务器缓存、选择合适图片格式等,旨在提升网页速度和用户体验。服务工作者、异步加载和响应式设计也是关键。持续学习新技术以适应不断变化的优化需求。
1521 1

热门文章

最新文章

下一篇
开通oss服务