await 不是阻塞指令,而是暂停当前 async 函数执行、交还控制权给事件循环的语法糖;它仅保证同一函数内 await 语句顺序执行,不阻塞 js 线程,也不影响其他任务调度。

await 不会“强制”顺序化,而是让代码在逻辑上表现为顺序执行,实际仍基于 Promise 和事件循环机制运行。
await 本质是语法糖,不是阻塞指令
它只是 暂停当前 async 函数的执行,把控制权交还给事件循环,等右侧 Promise settled(fulfilled 或 rejected)后再继续。JS 线程并未被阻塞,其他任务(如定时器、网络回调)照常运行。
- 写法
const data = await fetch('/api').then(res => res.json())等价于手动链式 .then(),但更易读 - 若 Promise 被 reject,且没用 try/catch 捕获,async 函数会返回 rejected Promise,不会静默失败
- await 后面不一定是 Promise:非 Promise 值会被自动包装成 resolved Promise(如
await 42立即返回 42)
顺序化只作用于同一 async 函数内
多个 await 语句在单个 async 函数中按书写顺序执行,但不同 async 函数之间互不影响。
- 错误理解:“await 让整个 JS 执行变同步”——实际只暂停当前函数,不影响宏任务/微任务队列调度
- 正确做法:需串行时,把 await 放在同一 async 函数里;需并行时,先启动所有 Promise,再 await Promise.all([...])
- 例如:
await api1(); await api2();是串行;const [a, b] = await Promise.all([api1(), api2()]);是并行
常见陷阱:误以为 await 能跨函数同步
async/await 只解决“函数内”的异步可读性问题,无法消除异步本质。调用 async 函数本身立即返回 Promise,不等待内部 await 完成。
- 错误写法:
function loadData() { await fetch('/data'); }—— 这函数没有 async 声明,await 会报语法错误 - 正确写法:
async function loadData() { return await fetch('/data').then(r => r.json()); },但调用时仍需loadData().then(...)或在另一个 async 函数里 await - 忘记处理错误:未包裹 try/catch 的 await 一旦失败,会中断后续语句,且错误向上冒泡到调用链
真正影响执行顺序的是 Promise 状态流转时机
await 的“顺序感”依赖 Promise 的 resolve/reject 时间点。如果多个 await 依赖同一个资源(如共享缓存),顺序可能被优化;如果 Promise 创建阶段就有副作用(如立即发起请求),则实际并发早已发生。
- 例:
const p1 = fetch('/a'); const p2 = fetch('/b'); await p1; await p2;—— 两个请求是并发发起的,只是结果处理顺序被 await 控制 - 若想真正延迟第二个请求,得写成
await fetch('/a'); await fetch('/b'); - 注意:Promise 构造函数中的执行器函数是同步运行的,await 只等它返回的 Promise 状态变化
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











