什么是JavaScript异步编程的核心机制_深入理解Promise与async/await【教程】

12次阅读

javaScript异步核心是Event Loop,它调度microtask(如promise.then)优先于task(如setTimeout),Promise executor同步执行,async/await基于Promise实现非阻塞暂停恢复。

什么是JavaScript异步编程的核心机制_深入理解Promise与async/await【教程】

javascript异步编程的核心机制不是 Promise 或 async/await 本身,而是 Event Loop —— 它决定了回调何时执行、Promise 状态如何流转、async 函数如何暂停与恢复。

Event Loop 怎么调度 Promise.then 和 setTimeout

很多人以为 Promise.then 是“立即执行”,其实它被推入 microtask queue;而 setTimeout 的回调进的是 task queue(也叫 macrotask queue)。microtask 总是清空完才处理下一个 task。

这意味着:

  • Promise.then 回调一定比同轮循环中的 setTimeout 先运行
  • 连续多个 Promise.then 会链式压入 microtask 队列,依次执行,不中断 js 线程
  • queueMicrotask 可手动插入 microtask,行为和 Promise.resolve().then() 一致
console.log(1); Promise.resolve().then(() => console.log(2)); setTimeout(() => console.log(3), 0); console.log(4); // 输出:1 → 4 → 2 → 3

Promise 构造函数里的 executor 是同步执行的

new Promise((resolve, reject) => { ... }) 时,传入的函数会**立刻同步执行**,不是“等异步时机到了再调”。这是最容易误解的一点。

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

常见误用场景:

  • 在 executor 里直接 return 而忘记调用 resolvereject → Promise 永远 pending
  • 误以为 Promise 自带“延迟”或“自动异步” → 实际上它只是对异步流程做状态封装
  • 在 executor 中抛出未捕获错误 → 等价于 reject(new Error(...)),但不会触发全局 unhandledrejection(除非没加 .catch
new Promise(resolve => {   console.log('executor runs now'); // 立刻打印   resolve('done'); }).then(console.log); // 'done'

async/await 不是语法糖,而是 Generator + Promise + 状态机的组合实现

async 函数返回一个 Promiseawait 并非阻塞线程,而是让出控制权,等右侧 Promise settled 后,再从上次暂停处继续执行(类似协程)。

关键细节:

  • await 后面如果不是 Promise,会被自动包装成 Promise.resolve(...)
  • await 只能在 async 函数内使用,顶层 await 仅在模块作用域(ESM)中合法
  • 多个 await 默认串行;想并发需用 Promise.all([p1, p2]) 包一层
  • try/catch 捕获的是 rejected Promise,不是 throw 的原始错误对象(但语义等价)
async function f() {   const a = await Promise.resolve(1); // 不是阻塞,是暂停+注册 microtask   const b = await Promise.resolve(2);   return a + b; } f().then(console.log); // 3

真正容易被忽略的是:Promise 链的错误传播依赖每个环节是否显式处理,而 async/await 的 try/catch 只覆盖当前 await 表达式——漏掉一个 catch,就可能让 rejection 逃逸成 unhandledrejection。这在复杂嵌套或条件分支中尤其危险。

text=ZqhQzanResources