0

0

JavaScript Promise.allSettled 任务计时与性能分析

心靈之曲

心靈之曲

发布时间:2025-11-06 21:25:19

|

595人浏览过

|

来源于php中文网

原创

JavaScript Promise.allSettled 任务计时与性能分析

本文详细介绍了如何在javascript中使用`promise.allsettled`并发执行多个异步任务时,有效记录并访问每个任务的独立完成时间。通过在promise链中集成时间戳捕获逻辑,我们可以精确分析各个任务的性能表现,识别潜在的性能瓶颈,并据此优化并发策略,例如评估任务分组执行的效率,以提升应用的响应速度和资源利用率。

在现代Web应用和Node.js服务中,处理多个异步操作(如API调用、文件读写或数据库查询)是常见的场景。Promise.allSettled()是一个强大的工具,它允许我们并发执行一组Promise,并在所有Promise都已解决(fulfilled)或拒绝(rejected)后,返回一个包含每个Promise最终状态和结果的数组。然而,Promise.allSettled()本身并不提供每个任务完成所需的时间信息。在进行性能分析或优化时,了解每个独立任务的耗时至关重要,例如,判断将一组任务拆分为多批次执行是否能提高整体效率。

1. 利用 finally() 记录任务完成时间

要获取每个Promise的独立完成时间,我们可以在将Promise传递给Promise.allSettled()之前,对其进行包装。Promise.prototype.finally()方法在Promise无论成功还是失败时都会执行其回调函数,这使得它成为记录完成时间的理想位置。

方法一:通过控制台输出计时信息

最直接的方法是在每个Promise完成时,立即将其耗时输出到控制台。这种方法适用于快速调试和初步性能观察。

/**
 * 包装 Promise 数组,并在每个 Promise 完成时记录其耗时到控制台。
 * @param {Array>} promises - 待执行的 Promise 数组。
 * @returns {Promise[]>} - Promise.allSettled 的结果。
 */
function allSettledTimedLog(promises) {
    const startTime = Date.now(); // 记录批处理开始时间

    // 使用 map 包装每个 Promise,在其 finally 回调中记录完成时间
    const timedPromises = promises.map((p, index) => {
        return p.finally(() => {
            // 计算当前 Promise 完成时距离批处理开始的时间
            console.log(`[任务 ${index}] 完成,耗时:${Date.now() - startTime}ms`);
        });
    });

    return Promise.allSettled(timedPromises);
}

代码解析:

立即学习Java免费学习笔记(深入)”;

  1. startTime = Date.now(): 在allSettledTimedLog函数开始时记录一个全局的起始时间。所有任务的耗时都将相对于这个时间点计算。
  2. promises.map((p, index) => { ... }): 遍历输入的Promise数组,为每个Promise创建一个新的Promise链。
  3. p.finally(() => { ... }): 在原始Promise p解决或拒绝时,finally回调会被执行。
  4. console.log(...): 在finally回调中,计算Date.now() - startTime,得到当前Promise完成时相对于批处理开始的耗时,并打印出来。
  5. return Promise.allSettled(timedPromises): 将所有被包装过的Promise传递给Promise.allSettled,确保所有任务都执行完毕。

使用示例:

const task1 = new Promise(resolve => setTimeout(() => resolve('任务1完成'), 1000));
const task2 = new Promise((_, reject) => setTimeout(() => reject('任务2失败'), 500));
const task3 = new Promise(resolve => setTimeout(() => resolve('任务3完成'), 1500));

allSettledTimedLog([task1, task2, task3])
    .then(results => {
        console.log('所有任务批处理结果:', results);
    });
// 预期输出示例:
// [任务 1] 完成,耗时:~500ms
// [任务 0] 完成,耗时:~1000ms
// [任务 2] 完成,耗时:~1500ms
// 所有任务批处理结果: [...]

这种方法简单直观,但计时信息只在控制台输出,没有与Promise.allSettled返回的结果对象关联。

magento(麦进斗)
magento(麦进斗)

Magento是一套专业开源的PHP电子商务系统。Magento设计得非常灵活,具有模块化架构体系和丰富的功能。易于与第三方应用系统无缝集成。Magento开源网店系统的特点主要分以下几大类,网站管理促销和工具国际化支持SEO搜索引擎优化结账方式运输快递支付方式客户服务用户帐户目录管理目录浏览产品展示分析和报表Magento 1.6 主要包含以下新特性:•持久性购物 - 为不同的

下载

方法二:将计时信息嵌入到 Promise.allSettled 结果中

如果需要将每个任务的耗时作为其结果的一部分返回,以便后续程序化处理,我们可以将计时信息存储在一个临时数组中,并在Promise.allSettled完成后,将其合并到最终结果对象中。

/**
 * 包装 Promise 数组,并将每个 Promise 的耗时嵌入到 Promise.allSettled 的结果对象中。
 * @param {Array>} promises - 待执行的 Promise 数组。
 * @returns {Promise & { time?: number }>>} - 包含计时信息的 Promise.allSettled 结果。
 */
function allSettledTimedEmbed(promises) {
    const startTime = Date.now();
    const taskTimes = new Array(promises.length); // 用于存储每个任务的耗时

    const timedPromises = promises.map((p, index) => {
        return p.finally(() => {
            // 在 finally 中记录当前任务的耗时到 taskTimes 数组
            taskTimes[index] = Date.now() - startTime;
        });
    });

    // 等待所有 Promise 完成,然后将计时信息合并到结果中
    return Promise.allSettled(timedPromises).then(results => {
        for (let i = 0; i < results.length; i++) {
            // 将耗时信息添加到对应的结果对象中
            results[i].time = taskTimes[i];
        }
        return results;
    });
}

代码解析:

立即学习Java免费学习笔记(深入)”;

  1. taskTimes = new Array(promises.length): 创建一个与输入Promise数组长度相同的数组,用于临时存储每个任务的耗时。
  2. p.finally(() => { taskTimes[index] = Date.now() - startTime; }): 同样在finally回调中计算耗时,但这次是将其存储到taskTimes数组的对应位置。
  3. Promise.allSettled(timedPromises).then(results => { ... }): 在所有被包装的Promise都完成后,Promise.allSettled会返回一个结果数组。我们在这里链式调用.then()来处理这个结果。
  4. for (let i = 0; i
  5. return results: 返回经过修改,包含计时信息的最终结果数组。

使用示例:

const apiCall1 = new Promise(resolve => setTimeout(() => resolve('API 1 数据'), 800));
const apiCall2 = new Promise((_, reject) => setTimeout(() => reject(new Error('API 2 失败')), 300));
const apiCall3 = new Promise(resolve => setTimeout(() => resolve('API 3 数据'), 1200));

allSettledTimedEmbed([apiCall1, apiCall2, apiCall3])
    .then(resultsWithTiming => {
        console.log('包含计时信息的所有任务结果:', resultsWithTiming);
        // 示例:分析耗时
        resultsWithTiming.forEach((result, index) => {
            console.log(`任务 ${index} 状态: ${result.status}, 耗时: ${result.time}ms`);
        });
    });
// 预期输出示例:
// 包含计时信息的所有任务结果: [
//   { status: 'rejected', reason: Error: API 2 失败, time: ~300 },
//   { status: 'fulfilled', value: 'API 1 数据', time: ~800 },
//   { status: 'fulfilled', value: 'API 3 数据', time: ~1200 }
// ]
// 任务 0 状态: fulfilled, 耗时: ~800ms
// 任务 1 状态: rejected, 耗时: ~300ms
// 任务 2 状态: fulfilled, 耗时: ~1200ms

这种方法提供了更强大的功能,因为计时数据直接与每个任务的结果相关联,便于后续的数据处理和分析。

注意事项与最佳实践

  1. 输入类型: 上述两种实现都假定promises参数是一个可迭代的数组,因为它使用了.map()方法。如果需要支持任意可迭代对象(如Set或Map),则需要额外代码将其转换为数组或使用for...of循环。
  2. 计时精度: Date.now()返回的是自Unix纪元以来的毫秒数。对于大多数性能分析场景,其精度已足够。在浏览器环境中,如果需要更高精度的计时(例如微秒级别),可以使用performance.now(),但它返回的是页面加载以来的毫秒数,且不适用于Node.js环境。
  3. finally 的作用: finally回调函数不接受任何参数,也不会改变Promise的最终状态或值/原因。它仅用于执行清理或记录等副作用操作,非常适合计时。
  4. 性能分析目的: 获取单个任务的耗时有助于识别批处理中的“慢任务”。通过分析这些数据,可以决定是否需要:
    • 优化慢任务本身。
    • 调整并发策略,例如将耗时差异大的任务分组,优先处理快速任务。
    • 实施超时机制,防止单个慢任务阻塞整个批处理。

总结

通过在Promise.allSettled()执行前,巧妙地利用Promise.prototype.finally()方法包装每个Promise,我们能够精确地记录并获取每个异步任务的独立完成时间。无论是通过控制台日志进行快速观察,还是将计时信息嵌入到返回的结果中进行进一步的程序化分析,这些技术都为我们提供了强大的工具,以更好地理解和优化JavaScript中并发异步操作的性能。这对于构建响应迅速、资源高效的应用程序至关重要。

相关文章

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

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

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
length函数用法
length函数用法

length函数用于返回指定字符串的字符数或字节数。可以用于计算字符串的长度,以便在查询和处理字符串数据时进行操作和判断。 需要注意的是length函数计算的是字符串的字符数,而不是字节数。对于多字节字符集,一个字符可能由多个字节组成。因此,length函数在计算字符串长度时会将多字节字符作为一个字符来计算。更多关于length函数的用法,大家可以阅读本专题下面的文章。

924

2023.09.19

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

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

75

2025.09.05

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

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

36

2025.11.16

golang map原理
golang map原理

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

60

2025.11.17

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

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

41

2025.11.27

js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

514

2023.06.20

js获取当前时间
js获取当前时间

JS全称JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,主要用于Web,常用来为网页添加各式各样的动态功能。js怎么获取当前时间呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

244

2023.07.28

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

298

2023.08.03

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

158

2026.01.28

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.3万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.5万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号