什么是async/await_它如何让代码更清晰

async/await 是基于 Promise 的语法糖,使异步代码更直观;async 函数自动返回 Promise,await 在 async 内暂停执行并等待 Promise 完成,支持 try/catch 统一错误处理,但需避免滥用导致性能下降。

async/await 是 JavaScript 中处理异步操作的语法糖,它基于 Promise,但让异步代码写起来像同步代码一样直观,大幅减少回调嵌套和 then 链,提升可读性和可维护性。

async 函数:自动返回 Promise

在函数声明前加 async,该函数就变成异步函数,无论内部是否含 await,它总会返回一个 Promise。如果函数返回普通值(比如字符串或数字),JavaScript 会自动用 Promise.resolve() 包装;如果抛出错误,则等价于 Promise.reject()

  • async function fetchData() { return "done"; }
    fetchData() // 返回 Promise
  • 不加 async 的普通函数无法直接使用 await,会报语法错误

await:暂停执行,等待 Promise 完成

await 只能在 async 函数内部使用,它会让 JS 引擎“暂停”当前函数的执行(不阻塞主线程),等右侧的 Promise settle(fulfilled 或 rejected)后再继续。await 后面可以是 Promise、任意值,甚至 undefined —— 非 Promise 值会被自动转为已兑现的 Promise。

  • const data = await fetch('/api/user').then(r => r.json());
    比纯 Promise 链更接近自然语言:“等接口返回,再解析 JSON”
  • await 不会“卡住”整个程序,只是暂停当前 async 函数,其他任务(如事件、定时器)照常运行

错误处理更贴近同步逻辑

try/catch 就能捕获 await 失败的 Promise,不需要每个 then 都配一个 catch,也不用把错误处理分散在链尾。多个 await 可共用一套 try/catch,结构清晰,堆栈也更真实。

  • async function loadProfile() {
      try {
        const user = await api.getUser();
        const posts = await api.getPosts(user.id);
        return { user, posts };
      } catch (err) {
        // 任一 await 出错都会进这里
        console.error("加载失败", err);
      }
    }

避免常见误区

await 并不是“让代码变快”,它只是让写法更线性;也不是“阻塞浏览器”,底层仍是事件循环驱动。滥用 await(比如本可并行的请求串行 await)反而会拖慢性能。

  • 需要并发请求时,先发起所有 Promise,再 await Promise.all([p1, p2])
  • await 后面不要跟没有返回 Promise 的函数(除非你明确想等它,且它返回的是 Promise)
  • 顶层 await 在模块中可用(ES2025+),但在普通脚本或函数外直接写 await 仍会报错