讲师中心 微信公众号
AI工具推荐 视频效率加速

如何并行执行多个 Promise 并按原始顺序获取结果

冬涛君_4958

冬涛君_4958

发布时间:2026-02-10 23:17:53

|

251人浏览过

|

来源于php中文网

原创

如何并行执行多个 Promise 并按原始顺序获取结果

本文介绍使用 `promise.all()` 实现 promise 并行执行与顺序返回的高效方案,替代手动维护队列的复杂逻辑,兼顾性能与可读性。

在 JavaScript 异步编程中,一个常见需求是:同时启动多个异步任务(充分利用并发能力),但确保最终结果严格按任务创建/提交的顺序被处理。例如,在持续拉取链上交易日志(getSwaps())的长时运行流程中,每个日志需异步处理(如休眠模拟 I/O、写入数据库),但数据库写入必须保持原始事件顺序,否则将导致数据错乱。

此时,自行实现类似 PromiseQueue 的串行调度器(如问题中基于递归 #dequeue 的类)虽可行,却存在明显缺陷:

  • ❌ 违背并发初衷:所有 Promise 实际被强制串行等待,无法并行执行;
  • ❌ 逻辑冗余:需手动管理队列、状态、回调链,易出错且难以调试;
  • ❌ 资源浪费:长时间运行场景下,内存中堆积未 resolve 的 resolve 函数引用,存在潜在泄漏风险。

正确解法是——Promise.all()。它天然满足两大核心要求:
✅ 并行执行:所有传入的 Promise 立即启动(无阻塞等待);
✅ 顺序返回:结果数组索引严格对应输入 Promise 的声明顺序(非完成顺序)。

以下为优化后的完整实现:

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

function randomNumber(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

// 模拟异步数据源(替换为实际的 for await...of 逻辑)
async function* getSwaps() {
    for (let i = 0; i < 20; i++) {
        yield { id: i };
    }
}

async function run() {
    const promises = []; // 存储所有待执行的 Promise 实例

    // 【关键】立即创建并推入 Promise(并行启动)
    for await (const log of getSwaps()) {
        const i = log.id;
        const promise = (async () => {
            await sleep(randomNumber(300, 1000)); // 模拟异步处理
            return i; // 返回结果(将按原始顺序出现在结果数组中)
        })();
        promises.push(promise);
    }

    // 【关键】Promise.all 并行等待,结果按 promises 数组索引顺序排列
    try {
        const results = await Promise.all(promises);
        results.forEach((value, index) => {
            console.log(`[Index ${index}] Result:`, value);
            // ✅ 此处可安全执行顺序敏感操作,如写入数据库
            // writeDataToDB(value);
        });
    } catch (error) {
        console.error('At least one promise rejected:', error);
        // 注意:Promise.all 遇任一拒绝即整体拒绝,如需容错请改用 Promise.allSettled
    }
}

run();

⚠️ 重要注意事项

  • 闭包陷阱:示例中 for await 循环内直接使用 log.id 而非循环变量 i(避免经典 var 提升问题),若用普通 for (let i...) 则 let 已确保块级作用域,无需额外处理。
  • 错误处理:Promise.all() 是“全或无”策略——任一 Promise 拒绝,整个调用即拒绝。若需独立处理每个 Promise 的成功/失败状态,请改用 Promise.allSettled(),它始终返回包含 {status, value/reason} 的结果数组。
  • 内存与流控:对“可能运行数小时”的海量数据流(如问题所述),直接累积所有 Promise 到数组可能导致内存溢出。此时应结合分批处理(如每 100 个一组调用 Promise.all)或使用 for await + 限流队列(如 p-map 库),而非完全放弃并行。

✅ 总结

Promise.all() 是解决“并行执行、顺序消费”场景的标准、简洁、高性能方案。它消除了手工队列调度的复杂性,让代码更接近业务意图——专注定义任务,而非调度细节。在保证结果顺序性的前提下,最大化异步并发效率,是现代 JavaScript 异步编程的基石实践之一。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

相关专题

更多
堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

6467

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2708

2023.08.10

go语言闭包相关教程大全
go语言闭包相关教程大全

本专题整合了go语言闭包相关数据,阅读专题下面的文章了解更多相关内容。

4813

2025.07.29

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

670

2025.09.05

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

343

2025.11.16

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

533

2025.11.17

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

303

2025.11.27

promise的用法
promise的用法

“promise” 是一种用于处理异步操作的编程概念,它可以用来表示一个异步操作的最终结果。Promise 对象有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。Promise的用法主要包括构造函数、实例方法(then、catch、finally)和状态转换。

4720

2023.10.12

Uvicorn 报错与问题解决教程
Uvicorn 报错与问题解决教程

本专题汇总了Uvicorn服务器常见问题与报错解决的教程合集,涵盖启动失败、端口占用、模块导入错误、事件循环冲突及热重载失效等典型故障的排查思路。同时整理了多进程与Worker配置、SSL/HTTPS证书报错、跨域与代理配置等实战解决方案,助你快速定位并解决Uvicorn运行中的各类问题。

20

2026.11.02

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn