JavaScriptPromise执行顺序详解
**JavaScript Promise 执行顺序解析:深入理解异步并发与微任务队列** Promise 作为 JavaScript 中处理异步操作的核心机制,其执行顺序并非线性,而是受到微任务队列的深刻影响。本文旨在深入解析 Promise 的执行机制,揭示多个独立 Promise 链并发执行时,then 回调如何被添加到微任务队列,以及 JavaScript 引擎如何调度这些任务。我们将通过示例代码,生动演示 Promise 链之间执行顺序的不确定性,并提供模拟 Promise 执行顺序的方法,帮助开发者理解和预测 Promise 的行为。掌握 Promise 的执行原理,对于编写健壮、可预测的异步代码至关重要,避免潜在的 bug 和意想不到的结果,提升 Web 应用的性能和稳定性。

“JavaScript Promise 的执行顺序并非完全线性,而是受到微任务队列的影响。多个独立的 Promise 链会并发执行,其 then 回调会被添加到微任务队列中,并在当前执行栈清空后依次执行。因此,Promise 链之间的执行顺序是不确定的,可能导致意想不到的结果。本文将深入探讨 Promise 的执行机制,并通过示例代码演示如何理解和预测 Promise 的执行顺序。”
Promise 是 JavaScript 中处理异步操作的重要机制。理解 Promise 的执行顺序,特别是当存在多个独立的 Promise 链时,对于编写健壮且可预测的异步代码至关重要。
Promise 的执行机制:微任务队列
Promise 的核心在于其异步特性。当一个 Promise resolve 或 reject 时,与其关联的 then 或 catch 回调函数并不会立即执行。相反,这些回调函数会被添加到微任务队列中。
微任务队列是一个先进先出的队列,用于存放需要在当前 JavaScript 任务执行完毕后立即执行的任务。常见的微任务包括 Promise 的回调、MutationObserver 的回调等。
JavaScript 引擎会优先处理当前执行栈中的代码,当执行栈为空时,才会检查微任务队列,并依次执行队列中的微任务。这个过程会持续进行,直到微任务队列为空。
多个 Promise 链的并发执行
当存在多个独立的 Promise 链时,每个链的 then 回调都会被添加到微任务队列中。由于 JavaScript 是单线程的,这些 Promise 链实际上是并发执行的,而不是串行执行。
这意味着,Promise 链之间的执行顺序是不确定的,取决于 JavaScript 引擎如何调度微任务队列中的任务。
考虑以下代码:
Promise.resolve() .then(() => console.log(1)) .then(() => console.log(2)) .then(() => console.log(3)); Promise.resolve() .then(() => console.log(11)) .then(() => console.log(12)); Promise.resolve() .then(() => console.log(111)) .then(() => console.log(122));
这段代码创建了三个独立的 Promise 链。期望的输出可能是 1, 2, 3, 11, 12, 111, 122,但实际输出可能不同,例如 1, 11, 111, 2, 12, 122, 3。
这是因为每个 then 回调都被添加到微任务队列中,JavaScript 引擎会根据其内部调度机制来决定执行顺序。
模拟 Promise 执行顺序
为了更好地理解 Promise 的执行顺序,可以使用以下代码来模拟所有可能的排列组合,并验证其是否符合 Promise 的执行规则:
const sequence = [1, 2, 3, 11, 12, 111, 122];
const rules = [
// All Promises
{ type: 'condition', operator: 'lt', left: 1, right: 11 },
{ type: 'condition', operator: 'lt', left: 11, right: 111 },
// 1st Promise
{ type: 'condition', operator: 'gt', left: 2, right: 1 },
{ type: 'condition', operator: 'gt', left: 3, right: 2 },
// 2nd Promise
{ type: 'condition', operator: 'gt', left: 12, right: 11 },
// 3rd Promise
{ type: 'condition', operator: 'gt', left: 122, right: 111 }
];
const main = () => {
const validPermutations = permutator(sequence)
.filter(p => validate(p, rules));
validPermutations.forEach((p, i) => {
console.log(`Permutation #${i + 1}: ${JSON.stringify(p).replace(/,/g, ', ')}`)
});
console.log('Valid permutations:', validPermutations.length);
};
const validate = (sequence, rules) => {
return rules.every(rule => {
switch (rule.type) {
case 'condition':
const
indexLeft = sequence.indexOf(rule.left),
indexRight = sequence.indexOf(rule.right);
switch (rule.operator) {
case 'gt':
return indexLeft > indexRight;
case 'lt':
return indexLeft < indexRight;
default:
return false;
}
break;
default:
return false;
}
});
};
const permutator = (inputArr) => {
const result = [];
permute(inputArr, result);
return result;
}
const permute = (arr, res, m = []) => {
if (arr.length === 0) res.push(m);
else {
for (let i = 0; i < arr.length; i++) {
const curr = arr.slice(), next = curr.splice(i, 1);
permute(curr.slice(), res, m.concat(next));
}
}
}
main();这段代码首先定义了一个 sequence 数组,包含了所有需要打印的值。然后定义了一组 rules,用于验证排列组合是否符合 Promise 的执行规则。例如,{ type: 'condition', operator: 'lt', left: 1, right: 11 } 表示 1 必须在 11 之前执行。
permutator 函数用于生成所有可能的排列组合,validate 函数用于验证排列组合是否符合规则。main 函数则负责生成所有有效的排列组合,并打印结果。
运行这段代码,可以观察到存在多个有效的排列组合,这说明 Promise 的执行顺序确实是不确定的。
注意事项与总结
- 理解 Promise 的执行机制,特别是微任务队列的概念,对于编写可预测的异步代码至关重要。
- 当存在多个独立的 Promise 链时,要注意它们是并发执行的,执行顺序是不确定的。
- 尽量避免依赖 Promise 链之间的执行顺序,可以使用 async/await 或其他同步机制来控制执行流程。
- 在需要严格控制执行顺序的场景下,可以将多个 Promise 链合并为一个链,或者使用 Promise.all 或 Promise.allSettled 来并行执行多个 Promise,并在所有 Promise 完成后执行后续操作。
通过深入理解 Promise 的执行机制,并结合实际代码示例,可以更好地掌握 Promise 的使用,编写出更加健壮和可维护的异步代码。
本篇关于《JavaScriptPromise执行顺序详解》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于文章的相关知识,请关注golang学习网公众号!
B站粉丝牌等级攻略及升级方法
- 上一篇
- B站粉丝牌等级攻略及升级方法
- 下一篇
- PHP多线程编程:pthreads扩展实战教程
-
- 文章 · 前端 | 2小时前 | 性能优化 · javascript · SharedArrayBuffer 前端性能 Atomics 跨源隔离 Web Worker
- Web Worker 配合 SharedArrayBuffer 共享高频数据
- 301浏览 收藏
-
- 文章 · 前端 | 4小时前 |
- View Transitions API 处理跨页面导航动画
- 310浏览 收藏
-
- 文章 · 前端 | 14小时前 | React useOptimistic 失败回滚 并发更新
- React useOptimistic 如何处理失败回滚与并发更新
- 286浏览 收藏
-
- 文章 · 前端 | 16小时前 |
- Vite 环境 API 如何为多运行时组织构建配置
- 418浏览 收藏
-
- 文章 · 前端 | 18小时前 |
- Web Locks API 的等待请求如何支持用户主动取消
- 239浏览 收藏
-
- 文章 · 前端 | 23小时前 | javascript · AbortController AbortSignal.any AbortError TimeoutError AbortSignal reason
- AbortSignal.any 触发后怎样判断来自超时还是手动取消
- 447浏览 收藏
-
- 文章 · 前端 | 1天前 |
- JavaScript Iterator Helpers 怎样组合惰性数据处理
- 110浏览 收藏
-
- 文章 · 前端 | 1天前 | css ·
- CSS 容器样式查询如何根据父级状态改组件
- 120浏览 收藏
-
- 文章 · 前端 | 1天前 | prefetch 前端性能 Speculation Rules API prerender
- Speculation Rules API 如何安全预渲染下一页
- 202浏览 收藏
-
- 文章 · 前端 | 1天前 | javascript · 前端性能 长任务 INP优化 交互延迟 web-vitals Long Animation Frames
- INP 偏高时如何定位长任务与交互延迟
- 257浏览 收藏
-
- 文章 · 前端 | 1天前 |
- HTML Popover API 怎样处理嵌套弹层与焦点
- 356浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 403次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 480次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 491次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 436次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 262次使用
-
- JavaScript函数定义及示例详解
- 2025-05-11 502浏览
-
- 智能体安全引领产业升级——国内AI安全产品市场深度分析
- 2026-08-21 501浏览
-
- CSS变量简化按钮悬停效果技巧
- 2026-05-31 501浏览
-
- JavaScript符号类型详解与应用
- 2026-05-31 501浏览
-
- HTML剪贴板复制粘贴怎么用
- 2026-05-26 501浏览

