async/await 异步总结:本质是什么?如何并发?怎么处理错误?
面试速答(30 秒版 TL;DR)
async函数一定返回 Promise;return x等价于Promise.resolve(x),throw e等价于Promise.reject(e)。await p会“暂停”当前async函数的后续执行,把后半段放到 微任务(microtask) 中继续执行。- 并发要点:多个独立请求不要串行
await,用Promise.all(或allSettled)并发。 - 错误处理:
try/catch包住await,或在调用处.catch;并发时注意Promise.all失败即短路。
本质:语法糖 + Promise + 微任务
你可以用一句话回答追问:
async/await是基于 Promise 的语法糖,让异步写法更像同步流程,但调度仍走事件循环与微任务队列。
返回值与异常
async function f() {
return 1;
}
f().then(console.log); // 1
async function g() {
throw new Error("x");
}
g().catch((e) => console.log(e.message)); // "x"
串行 vs 并发(面试高频)
串行(慢):
const a = await fetchA();
const b = await fetchB();
并发(快):
const [a, b] = await Promise.all([fetchA(), fetchB()]);
不想短路,用 allSettled:
const rs = await Promise.allSettled([fetchA(), fetchB()]);
错误处理模板
async function load() {
try {
const data = await fetchJSON();
return data;
} catch (e) {
// 记录、降级、重试等
throw e;
} finally {
// 清理资源
}
}
典型追问:await 会阻塞线程吗?
答法要点:
- 不会阻塞 JS 主线程执行其他任务(事件循环照常跑)。
- 它只会暂停当前
async函数的后续语句执行,等 Promise settle 后再以微任务继续。
易错点/坑
- 在循环里无脑
await导致串行:能并发就并发。 - 忘记处理并发失败策略:
Promise.all任一失败就 reject。 await只等 Promise:对普通值相当于立即Promise.resolve。
速记要点(可背诵)
async返回 Promise;await让后续进入微任务继续。- 并发用
Promise.all,不短路用allSettled。 - 错误用
try/catch或.catch兜底。