游乐游手机版
首页/前端开发/文章详情

Promise核心状态变化过程实现原理

时间:2026-07-17 07:05
Promise实例初始为pending状态,通过resolve或reject触发单向不可逆转换至fulfilled或rejected。状态变更具有原子性,先判后改,避免竞态。状态锁定后触发对应回调队列,通过微任务调度异步执行,执行器同步运行确保状态可控。

想要深入掌握 Promise 的运行机制,就必须先剖析其底层的状态机模型。核心原理其实就六个字:单向、不可逆、不可回退。理解 Promise 的关键,全在于这套状态变化的规则体系。

Promise 的核心状态变化过程是怎么实现的

每一个 Promise 实例从创建的那一刻起,就处于三种状态之一:pending(待定)fulfilled(已成功)rejected(已失败)。状态的转换由执行器(executor)中显式调用的 resolvereject 函数触发。一旦状态确定,便永久锁定,无法再更改。

状态只有三种,且严格单向转移

每个 Promise 实例在任何时刻都只属于以下一种状态:

  • pending:初始阶段,既未成功也未失败,允许状态转变
  • fulfilled:成功态,由 resolve(value) 触发,之后状态固化,不可再变
  • rejected:失败态,由 reject(reason) 触发,同样永久锁定

状态之间的变更路径只有两条:pending → fulfilledpending → rejected。一旦进入已完成或已拒绝状态,后续再调用 resolvereject 都会被忽略。这就是“单向不可逆”的直观体现。

状态变更的原子性保障

每次调用 resolvereject 时,内部会先检查当前状态是否仍为 pending

  • 如果不是 pending,直接返回,不执行任何操作
  • 如果是 pending,才更新 this.state,并保存 this.valuethis.reason

这种“先判断后修改”的原子性逻辑,确保了状态变更不会被重复或覆盖,竞态条件自然不复存在。换句话说,最先调用的 resolvereject 决定了最终结果,后续调用都只能作为旁观者。

状态改变后触发对应回调

Promise 内部维护了两个回调队列:onFulfilledCallbacksonRejectedCallbacks。当 then 被调用时,这些回调函数会被收集起来,等到状态真正变更后统一执行:

  • 状态变为 fulfilled → 遍历并执行所有成功回调,传入 this.value
  • 状态变为 rejected → 遍历并执行所有失败回调,传入 this.reason

这里有一个关键的实现细节:这些回调通过 queueMicrotask(微任务)进行调度。它们会在当前同步代码执行完毕后、下一个宏任务开始之前被执行。这正是 Promise 实现“异步但不延迟”的底层机制——你注册的回调不会立即执行,但也不会被推迟到遥远的定时器里。

执行器立即运行,状态即刻可控

new Promise 时,传入的 executor 函数会同步立即执行。这意味着,resolvereject 的调用时机完全由你掌控:

  • 可以立刻 resolve,创建一个已成功的 Promise
  • 可以在 setTimeout 后 reject,模拟异步失败场景
  • 也可以直接抛出异常,自动触发 reject

这种设计让 Promise 的状态起点非常清晰,整个过程完全可预测。正是基于这套稳固的状态机模型,链式调用和错误冒泡才能顺畅地运行起来。

来源:https://www.php.cn/faq/2824256.html
上一篇第三方网站访问后安全返回原应用的方法 下一篇JavaScript箭头函数传递剩余参数的常见用法与示例
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
uni-app小程序Canvas绘制超大图片报错问题的解决方案
前端开发 · 2026-07-17

uni-app小程序Canvas绘制超大图片报错问题的解决方案

iOSCanvas高度超4096px会静默失败,需分段绘制,每段控制在3800px内;导出需在draw回调内执行;H5跨域污染需设置crossOrigin或fetch中转;canvasId错误因组件未挂载,需确保DOM就绪。

HTML表格鼠标悬停整行加粗实现技巧
前端开发 · 2026-07-17

HTML表格鼠标悬停整行加粗实现技巧

表格行悬停加粗需避免内联样式或!important,建议用font-weight:700;统一作用于td和th;加粗后文字发虚可用text-rendering优化;注意tr:hover在display:grid下失效,移动端需加cursor:pointer。

HTML项目集成Prettier与ESLint双重质量保障配置
前端开发 · 2026-07-17

HTML项目集成Prettier与ESLint双重质量保障配置

Prettier默认不格式化Vue单文件组件及WXML等文件,需要手动绑定文档选择器;ESLint工具检查内联JavaScript代码必须借助eslint-plugin-html插件;另外,eslint-config-prettier与eslint-plugin-prettier需成对安装且顺序正确;并且,在VSCode编辑器内,还需开启prettier e

用background-clip防止HTML表格背景颜色溢出边框
前端开发 · 2026-07-17

用background-clip防止HTML表格背景颜色溢出边框

表格单元格默认背景色按边框盒渲染,覆盖半透明边框。解决需将背景裁剪设为内边距盒,并显式声明边框样式不为无,使边框真实存在。注意边框合并后裁剪边界变化,父容器溢出隐藏可能裁掉边框外延。

HTML表格用CAPTION标签添加说明的完整教程
前端开发 · 2026-07-17

HTML表格用CAPTION标签添加说明的完整教程

HTML表格的CAPTION标签必须紧跟在开始标签后、第一个之前,否则浏览器可能忽略。可用CSS控制位置,但需注意IE和旧版Safari兼容性。该标签对屏幕阅读器识别表格用途至关重要,不可省略或用其他元素替代,也不应代替表头行。