Async/Await是什么_如何让异步代码更易读【教程】

11次阅读

async/await 是 promise 的语法封装而非新语法糖,async 函数自动将返回值包装为 Promise,await 只能在 async 函数内使用,需注意串行与并发区别及错误处理机制。

Async/Await是什么_如何让异步代码更易读【教程】

Async/await 不是新语法糖,而是 Promise 的语法封装,它本身不改变异步行为,但能显著降低回调嵌套和 .then() 链的维护成本。

async 函数必须显式返回 Promise

声明为 async 的函数,无论内部是否 await,其返回值都会被自动包装成 Promise。这意味着:

  • 直接 return 42 → 实际返回 Promise.resolve(42)
  • return Promise.reject(new Error()) 不会再被包装,原样传出
  • 如果忘记 await 一个 async 函数调用,你拿到的是一个 pending 的 Promise,不是结果
async function getValue() {   return "done"; } console.log(getValue()); // Promise {} console.log(await getValue()); // "done"

await 只能在 async 函数内使用

试图在普通函数或顶层作用域中写 await 会触发 SyntaxError: await is only valid in async functions。常见误用场景包括:

  • iffor 块里直接 await(没包 async 函数)
  • node.js 14.8+ 支持顶层 await,但仅限 ES 模块(type: "module"),Commonjs 中仍非法
  • react 事件处理器onClick={() => await handleSubmit()} 会报错,必须写成 onClick={async () => {...}}

错误处理:不要只靠 try/catch,也要检查 rejected 状态

await 会让 rejected Promise 抛出异常,所以 try/catch 是主流做法。但要注意:

  • await Promise.all([p1, p2]) 任一失败即整体 reject,无法获知哪个出错 —— 改用 Promise.allSettled() 更稳妥
  • 对可能为 NULL 或非 Promise 的值调用 await 不会报错,但无意义(await 123 直接返回 123
  • 未捕获的 Promise rejection 会触发 unhandledrejection 事件,在 node.js 中可能导致进程退出
async 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   } }

性能陷阱:await 并不自动并发,顺序写 = 串行执行

这是最常被忽略的一点:await 是阻塞当前 async 函数执行流的,但不阻塞整个线程。连续写多个 await 就是串行,不是并行:

  • ❌ 错误示范(耗时 = t1 + t2):
    const a = await fetch("/a"); const b = await fetch("/b");
  • ✅ 正确做法(耗时 ≈ max(t1, t2)):
    const [a, b] = await Promise.all([fetch("/a"), fetch("/b")]);
  • 若需按序处理但又想提前发起请求,先发请求再 await
    const promiseA = fetch("/a"); const promiseB = fetch("/b"); const a = await promiseA; const b = await promiseB;

真正难的不是写 async/await,而是判断哪些操作该并发、哪些必须串行、哪些根本不需要 await —— 这些决定直接影响响应时间和资源利用率。

text=ZqhQzanResources