Promise 与 async/await
把 Promise 状态机与 async/await 语法糖放到同一模型,强调错误传播、并行与取消边界。
#type / synthesis
#status / growing
#tech / dev
#resource / javascript
#resource / ecmascript
[!info] 关联笔记
Promise 与 async/await
这个概念为什么出现
回调地狱让错误处理与并行组合失控。Promise 提供统一的一次性完成态;async/await 让异步流程用同步外形书写,但仍运行在事件循环上。
[!abstract] 一句话理解
async函数返回 Promise;await等待 Promise 兑现并把后续注册为微任务续体。
最小可运行示例
场景:拉取 SKU 详情再拉库存
function fetchSku(id) {
return Promise.resolve({ id, name: '缠绕膜' })
}
function fetchStock(id) {
return Promise.resolve({ id, qty: 3 })
}
async function loadSkuCard(id) {
// 业务意图:详情页需要名称与库存
// 教学点:await 失败会抛到 async 函数的 rejection
try {
const sku = await fetchSku(id)
const stock = await fetchStock(id) // 串行
return { ...sku, ...stock }
} catch (err) {
throw new Error('loadSkuCard failed: ' + err.message)
}
}
async function loadSkuCardFaster(id) {
// 教学点:独立请求用 Promise.all 并行
const [sku, stock] = await Promise.all([fetchSku(id), fetchStock(id)])
return { ...sku, ...stock }
}
loadSkuCard('A-01').then(console.log)
loadSkuCardFaster('A-01').then(console.log)
核心模型
| 概念 | 要点 |
|---|---|
| 状态 | pending → fulfilled/rejected,一锤定音 |
| then | 返回新 Promise,可链式转换 |
| async | 永远返回 Promise |
| await | 解包 Promise,错误变 throw |
| all/race/allSettled/any | 组合并发 |
边界
await在非 async 中非法(模块顶层 await 是特例)- 忘记
await会变成“火后忘记” - 取消需要
AbortController等,Promise 自身不自带取消语义
常见误区
[!warning] 常见误区:async 函数里同步 throw 与 reject 完全无关 同步 throw 会被包装成该 async 返回 Promise 的 rejection。
工程实践
- 并行能 all 就别无故串行 await
- 统一错误类型边界
- 与 UI 框架结合时注意竞态(过期响应)
本节总结
async/await 是可读性工具,Promise 才是契约;组合与错误传播决定系统稳健度。
自测题
async function f(){ return 1 }的返回值类型?- 两个独立 I/O 为何避免顺序 await?
参考答案
- Promise,兑现为 1。
- 顺序 await 拉长总等待;
Promise.all可重叠等待。