跳到主要内容

async/await 异步总结:本质是什么?如何并发?怎么处理错误?

面试速答(30 秒版 TL;DR)

  • async 函数一定返回 Promisereturn 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 兜底。