await 不会阻塞整个程序,只暂停当前 async 函数执行并让出控制权给事件循环;它实现协作式暂停,允许浏览器响应用户操作、处理其他异步任务,本质是等待 promise settled 后恢复执行而非同步阻塞。

await 不会阻塞整个程序,只暂停当前 async 函数的执行,让出控制权给事件循环。 它不是传统意义上的“阻塞”,而是一种协作式暂停——函数挂起,但 JavaScript 引擎可以继续处理其他任务(比如响应点击、定时器、其他异步操作)。
await 的实际效果:暂停当前函数,不冻结线程
当遇到 await promise 时:
- 如果 promise 已完成(fulfilled 或 rejected),立即取得结果,继续往下执行;
- 如果 promise 还未完成,当前 async 函数暂停,控制权交还给事件循环;
- 等 promise settled 后,函数从暂停处恢复(在微任务队列中排队执行)。
这期间浏览器依然响应用户操作,其他异步任务照常运行——它不锁主线程,也不像 sleep() 那样让 CPU 空转。
常见误解:await ≠ 同步阻塞
很多人以为 await fetch(...) 会让后续代码“卡住几秒”,其实:
- 网络请求发起后,JS 立即暂停该函数,但浏览器同时在后台处理 HTTP;
- 你写在
await后面的代码,要等响应到达、promise resolve 后才运行; - 同一时间,其他事件(如按钮点击、setTimeout 回调)仍可被处理。
所以它“看起来像阻塞”,本质是等待 + 恢复,不是冻结执行栈。
怎么写出真正“顺序等待”的逻辑
如果你希望 A 完成后再执行 B,B 完成后再执行 C,就按顺序写 await:
const a = await api.getA();const b = await api.getB(a.id);const c = await api.getC(b.ref);
这样三者串行执行,每一步都等前一步结果。但如果想并发执行再汇总,就该用 Promise.all([await ...]) 或先发请求再 await ——关键在 Promise 创建时机,不在 await 本身。
错误用法:在非 async 函数里用 await
await 只能在 async 函数内部使用。直接写:
-
❌ 错误:
const data = await fetch('/api'); // SyntaxError -
✅ 正确:
async function loadData() { const res = await fetch('/api'); }
顶层 await(Top-level await)只在模块作用域有效(如 ES module 的 .mjs 文件或现代打包工具支持的环境),普通脚本中必须包裹在 async 函数里。










