async/await 能替代 Promise.then 且更直观,本质是 Promise 的语法包装;await 只能在 async 函数中使用,顶层 await 需 ES 模块支持;需用 try/catch 正确捕获错误,注意并发控制与错误隔离。

async/await 是什么,它真能替代 Promise.then?
能,而且更直观。async/await 不是新语法糖,而是 Promise 的语法包装,底层完全基于 Promise。只要函数用 async 声明,它就自动返回一个 Promise;在函数体内用 await 等待的值,无论原本是不是 Promise,都会被自动 Promise.resolve() 包裹。
await 只能在 async 函数里用,但顶层 await 有例外
直接在模块顶层写 await 会报错 SyntaxError: await is only valid in async function,除非你:
- 在 ES 模块(
.mjs文件或type="module"的 script 标签中)启用顶层await—— 这是合法的,且浏览器和 Node.js 14.8+ 都支持 - 用 IIFE 包一层:
;(async () => { const data = await fetch('/api/user').then(r => r.json()) console.log(data) })() - 不滥用:多数业务逻辑仍应封装进
async函数,而非依赖顶层 await
try/catch 比 .catch() 更自然,但别漏掉错误边界
await 后抛出的错误不会冒泡到外层同步代码,必须用 try/catch 捕获。这比链式 .catch() 更贴近同步思维,但也容易误以为“没写 catch 就不会出错”。
常见疏忽:
- 忘记包裹整个 await 序列,比如只包了第一个
await fetch(),但后续res.json()可能失败,也要在同一个try块里 - 在循环中 await 多个请求时,没做错误隔离,一个失败导致整个流程中断 —— 此时应配合
Promise.allSettled()或单独 try/catch 每次调用 -
await后接的是可能为undefined或null的值时,直接链式调用会报Cannot read property 'xxx' of undefined,这不是 Promise rejection,catch捕不到
并发请求别盲目 await,注意串行 vs 并行
连续写多个 await 是串行执行,耗时累加;想并行,得先发起所有 Promise,再统一 await:
const [user, posts, comments] = await Promise.all([
fetch('/api/user').then(r => r.json()),
fetch('/api/posts').then(r => r.json()),
fetch('/api/comments').then(r => r.json())
])
关键点:
-
Promise.all()任意一个 reject 整体就失败;需要全部结果(含失败)请改用Promise.allSettled() - Node.js 中
await后跟普通函数调用(如await fs.readFile())仍是异步,但若该函数内部没真正异步(比如只是同步计算),await 就失去意义,还可能误导可读性 - V8 引擎对 async 函数有额外开销,高频小函数(如每帧调用的渲染逻辑)慎用,优先考虑纯同步或 Promise 缓存











