当前位置: 首页 > news >正文

Promise 构造函数与 `then` 方法的执行机制:同步与异步

🤍 前端开发工程师、技术日更博主、已过CET6
🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1
🕠牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》
🍚蓝桥云课签约作者、上架课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入门到实战全面掌握 uni-app》

在 JavaScript 中,Promise是一种用于处理异步操作的机制,但它在执行过程中涉及到同步和异步两种行为。理解Promise构造函数和then方法的执行机制对于正确使用Promise和避免潜在的错误至关重要。本文将深入探讨Promise构造函数和then方法的执行机制,并通过实际代码示例进行说明。

一、Promise 构造函数的执行机制

Promise构造函数用于创建一个新的Promise实例。它的语法如下:

constpromise=newPromise((resolve,reject)=>{// 执行逻辑});

(一)Promise 构造函数是同步执行的

Promise构造函数中的执行器(executor)是同步执行的。这意味着在new Promise被调用时,执行器函数会立即被调用,而不会等待异步操作完成。

示例 1:Promise 构造函数的同步执行

console.log("1. Start");constmyPromise=newPromise((resolve,reject)=>{console.log("2. Inside Promise executor");resolve("Promise resolved!");});console.log("3. End");

输出:

1. Start 2. Inside Promise executor 3. End

在这个例子中:

  1. 首先打印"1. Start"
  2. 然后执行Promise构造函数中的执行器函数,打印"2. Inside Promise executor"
  3. 最后打印"3. End"

可以看到,Promise构造函数中的执行器是同步执行的,它会立即运行,而不会等待异步操作完成。

(二)Promise 的状态改变是异步的

虽然Promise构造函数中的执行器是同步执行的,但Promise的状态改变(从pendingfulfilledrejected)是异步的。当调用resolvereject时,Promise的状态不会立即改变,而是被放入微任务队列(microtask queue)中,等待当前同步代码执行完毕后再处理。

示例 2:Promise 状态改变的异步性

console.log("1. Start");constmyPromise=newPromise((resolve,reject)=>{console.log("2. Inside Promise executor");resolve("Promise resolved!");console.log("3. After resolve");});console.log("4. End");myPromise.then((result)=>{console.log("5. Promise resolved:",result);});

输出:

1. Start 2. Inside Promise executor 3. After resolve 4. End 5. Promise resolved: Promise resolved!

在这个例子中:

  1. 首先打印"1. Start"
  2. 然后执行Promise构造函数中的执行器函数,打印"2. Inside Promise executor"
  3. 调用resolve后,打印"3. After resolve"
  4. 继续执行同步代码,打印"4. End"
  5. 最后,Promise的状态改变被放入微任务队列,当前同步代码执行完毕后,微任务队列中的任务被执行,打印"5. Promise resolved: Promise resolved!"

二、then方法的执行机制

Promise.prototype.then方法用于注册处理Promise成功或失败的回调函数。它的语法如下:

promise.then(onFulfilled,onRejected);

(一)then方法是异步执行的

then方法的回调函数是异步执行的。即使Promise的状态已经改变(例如,Promise已经被resolvereject),then方法中的回调函数也不会立即执行,而是被放入微任务队列中,等待当前同步代码执行完毕后再处理。

示例 3:then方法的异步执行

console.log("1. Start");constmyPromise=newPromise((resolve,reject)=>{console.log("2. Inside Promise executor");resolve("Promise resolved!");});console.log("3. End");myPromise.then((result)=>{console.log("4. Promise resolved:",result);});

输出:

1. Start 2. Inside Promise executor 3. End 4. Promise resolved: Promise resolved!

在这个例子中:

  1. 首先打印"1. Start"
  2. 然后执行Promise构造函数中的执行器函数,打印"2. Inside Promise executor"
  3. 调用resolve后,继续执行同步代码,打印"3. End"
  4. 最后,Promise的状态改变被放入微任务队列,当前同步代码执行完毕后,微任务队列中的任务被执行,打印"4. Promise resolved: Promise resolved!"

(二)then方法的链式调用

then方法返回一个新的Promise,因此可以链式调用。每个then方法的回调函数都会被放入微任务队列中,按照它们被注册的顺序依次执行。

示例 4:then方法的链式调用

console.log("1. Start");constmyPromise=newPromise((resolve,reject)=>{console.log("2. Inside Promise executor");resolve("Promise resolved!");});console.log("3. End");myPromise.then((result)=>{console.log("4. First then:",result);return"New value";}).then((result)=>{console.log("5. Second then:",result);});

输出:

1. Start 2. Inside Promise executor 3. End 4. First then: Promise resolved! 5. Second then: New value

在这个例子中:

  1. 首先打印"1. Start"
  2. 然后执行Promise构造函数中的执行器函数,打印"2. Inside Promise executor"
  3. 调用resolve后,继续执行同步代码,打印"3. End"
  4. 最后,Promise的状态改变被放入微任务队列,当前同步代码执行完毕后,微任务队列中的任务按顺序执行:
    • 第一个then的回调函数被调用,打印"4. First then: Promise resolved!",并返回"New value"
    • 第二个then的回调函数被调用,打印"5. Second then: New value"

三、同步与异步的总结

  1. Promise 构造函数

  2. then方法

四、实际应用中的注意事项

  1. 避免在Promise构造函数中直接调用resolvereject

  2. 正确处理错误

  3. 理解微任务队列

五、总结

Promise构造函数的执行器是同步执行的,但Promise的状态改变是异步的。then方法的回调函数也是异步执行的,它们会被放入微任务队列中,等待当前同步代码执行完毕后再处理。理解Promise的同步与异步行为对于正确使用Promise和避免潜在的错误至关重要。希望本文能够帮助你更好地理解Promise的执行机制,并在实际开发中合理使用它。

http://www.jsqmd.com/news/499670/

相关文章:

  • Local SDXL-Turbo效果展示:512x512分辨率下4K风格提示词的实际表现
  • C#+YOLO推理结果不对?90%的问题都是预处理/后处理写错了,一文讲透
  • 2026年知名的110kv预制舱厂家推荐:一二次预制舱口碑好的厂家推荐 - 品牌宣传支持者
  • Redis+免费可视化工具安装教程(附安装包)
  • 2026年箱包行业沃尔玛验厂咨询诚信服务商推荐:化妆品认证咨询、反恐验厂咨询、绿标认证咨询、翠鸟认证咨询、BRC认证咨询选择指南 - 优质品牌商家
  • MiniCPM-o-4.5-nvidia-FlagOS保姆级教程:模型量化部署(AWQ/GPTQ)可行性验证
  • 芯片验证自学入门教程
  • C#+YOLO开发10个必踩的坑,我帮你全踩过了,附完整解决方案
  • 红黑树介绍
  • SeqGPT-560M实战教程:结合LangChain构建带记忆的多轮信息补全工作流
  • BeyondMimic:从运动追踪到通过引导扩散实现多功能人形机器人控制
  • C#+YOLO 工业现场踩坑实录:产线环境的10个奇葩问题与“血泪”解决方案
  • C#+YOLO 模型量化后精度暴跌?一文教你 INT8 量化不丢精度的正确姿势
  • 如何定义一个 IoT 产品的核心用户价值
  • 2026四川悬挑工字钢租赁优质服务商推荐榜:老式工字钢租赁/路面钢板租赁/铁路钢板租赁/工地工字钢租赁/工地钢板租赁/选择指南 - 优质品牌商家
  • lite-avatar形象库惊艳效果展示:教师数字人授课场景下的自然微表情与唇动
  • 【案例共创】华为云码道生成表格提取助手,百份Word表格一键提取,秒变Excel!
  • 面试题总结
  • 【二维路径规划与定位】A*算法对二维障碍物平面的路径规划,结合TOA定位的MATLAB仿真代码。订阅专栏后可查看完整代码
  • C# WinForm+YOLO 视觉检测上位机开发:从零到上线,工业级可落地
  • 德电推出全球首个“多轨物联网漫游”:地面与太空首次“无缝切换”
  • Redis(Remote Dictionary Server)的应用场景与使用方法(基于内存的高性能NoSQL数据库,支持持久化,并提供多种数据结构)RDB、AOF、主从复制、哨兵、集群
  • 企业级CRM客户关系管理软件|ThinkPHP+FastAdmin开发|含源码+UniApp小程序/H5双端
  • WPF+YOLO 工业视觉上位机开发:MVVM 架构,美观又好维护
  • “龙虾“给AIoT的启示:机械臂有灵魂了,传感器变技能了,MES可以扔了
  • 养成记录好习惯(4)——Terraform离线部署(linux-amd64)
  • C#+YOLO 边缘计算实战:从桌面端到 RK3588/Jetson 全部署指南
  • 2026 本科毕业论文 AI 工具全盘点:9 款神器,高效搞定初稿、绘图与合规检测
  • Rithmic 14天/30天试用账号注册工具|支持ATAS、Bookmap等平台实时行情接入
  • 【Kubernetes知识点问答题】资源配额 / 访问控制