async/await 是 Promise 的语法封装而非新语法糖,async 函数自动将返回值包装为 Promise,await 只能在 async 函数内使用,需注意串行与并发区别及错误处理机制。
Async/await 不是新语法糖,而是 Promise 的语法封装,它本身不改变异步行为,但能显著降低回调嵌套和链的维护成本。
async 函数必须显式返回 Promise
声明为
的函数,无论内部是否
,其返回值都会被自动包装成 Promise。这意味着:
直接
→ 实际返回
不会再被包装,原样传出
如果忘记
一个 async 函数调用,你拿到的是一个 pending 的 Promise,不是结果
await 只能在 async 函数内使用
试图在普通函数或顶层
作用域
中写
会触发
。常见误用场景包括:
在
或
块里直接
(没包 async 函数)
Node.
js
14.8+ 支持顶层 await,但仅限 ES 模块(
),CommonJS 中仍非法
React 事件
处理器
如
会报错,必须写成
错误处理:不要只靠 try/catch,也要检查 rejected 状态
会让 rejected Promise 抛出异常,所以
是主流做法。但要注意:
php版微信js-sdk支付接口类
php版微信js-sdk支付接口类
下载
任一失败即整体 reject,无法获知哪个出错 —— 改用
更稳妥
对可能为
或非 Promise 的值调用
不会报错,但无意义(
直接返回
)
未捕获的 Promise rejection 会触发
事件,在 Node.js 中可能导致进程退出
性能陷阱:await 并不自动并发,顺序写 = 串行执行
这是最常被忽略的一点:
是阻塞当前 async 函数执行流的,但不阻塞整个线程。连续写多个
就是串行,不是并行:
❌ 错误示范(耗时 = t1 + t2):
✅ 正确做法(耗时 ≈ max(t1, t2)):
若需按序处理但又想提前发起请求,先发请求再
:
真正难的不是写
,而是判断哪些操作该并发、哪些必须串行、哪些根本不需要
—— 这些决定直接影响响应时间和资源利用率。
.then()asyncawaitreturn 42Promise.resolve(42)return Promise.reject(new Error())awaitasync function getValue() {
return "done";
}
console.log(getValue()); // Promise {}
console.log(await getValue()); // "done" awaitSyntaxError: await is only valid in async functionsifforawaittype: "module"onClick={() => await handleSubmit()}onClick={async () => {...}}awaittry/catchawait Promise.all([p1, p2])Promise.allSettled()nullawaitawait 123123unhandledrejectionasync function fetchBoth() {
try {
const [a, b] = await Promise.allSettled([
fetch("/api/user"),
fetch("/api/posts")
]);
if (a.status === "fulfilled") console.log(a.value);
if (b.status === "rejected") console.error(b.reason);
} catch (e) {
// 这里不会捕获 Promise.allSettled 的 rejection
}
}awaitawaitconst a = await fetch("/a");
const b = await fetch("/b");const [a, b] = await Promise.all([fetch("/a"), fetch("/b")]);awaitconst promiseA = fetch("/a");
const promiseB = fetch("/b");
const a = await promiseA;
const b = await promiseB;async/awaitawait