async/await 是 JavaScript 对协程思想的模拟实现,基于 Promise 的语法糖,通过暂停与恢复执行上下文实现异步流程的线性书写,简化嵌套、错误处理和控制流。

JavaScript 本身没有原生协程(coroutine)概念,但 async/await 是对协程思想的模拟实现——它让异步代码看起来像同步代码一样线性执行,同时不阻塞主线程。这种“类协程”机制,本质上是基于 Promise 的语法糖,配合引擎级的执行上下文暂停与恢复能力。
协程在 JS 中的体现:async/await 就是用户态的轻量级协程
传统协程可在执行中途挂起、保存状态、让出控制权,之后再从断点恢复。JS 中的 async 函数正是这样工作的:
- 遇到 await 时,函数暂停执行,控制权交还给事件循环,当前执行上下文被暂存(V8 会优化保留最小闭包)
- 等待的 Promise 被 resolve 或 reject 后,引擎自动恢复该函数的执行栈,从 await 下一行继续运行
- 整个过程对开发者透明,无需手动管理回调链或状态传递
它怎样简化异步编程?
相比回调和 Promise 链,async/await 把“异步流程”还原成直观的“顺序逻辑”,关键简化体现在三方面:
-
扁平化嵌套:避免多层
.then()或回调地狱。例如获取用户→订单→商品,可写成三行 await,而非三层嵌套 -
同步式错误处理:用
try/catch捕获异步错误,语义统一,不用在每个.catch()或回调里重复写错误逻辑 - 自然支持循环与条件分支:for/while/if 中直接 await,无需额外封装 Promise.all 或递归 setTimeout
注意:它不是真正的多线程协程
JS 仍是单线程、基于事件循环的模型。async/await 不创建新线程,也不并行执行代码——它只是让“等待异步结果”的过程不卡住主线程,并把恢复执行这件事自动化了。所谓“协程感”,来自执行流的可控暂停与恢复,而非并发调度。
立即学习“Java免费学习笔记(深入)”;
一个对比示例
顺序请求三个接口的传统 Promise 写法:
fetch('/user')
.then(res => res.json())
.then(user => fetch(`/orders/${user.id}`))
.then(res => res.json())
.then(orders => fetch(`/product/${orders[0].id}`))
.then(res => res.json())
.catch(err => console.error(err));
用 async/await 重写:
async function loadUserOrderProduct() {
try {
const user = await (await fetch('/user')).json();
const orders = await (await fetch(`/orders/${user.id}`)).json();
const product = await (await fetch(`/product/${orders[0].id}`)).json();
return product;
} catch (err) {
console.error(err);
}
}
逻辑清晰、调试友好、错误集中、易于扩展。











