信息发布→ 登录 注册 退出

javascript的async和await怎么用_它们如何简化异步代码?

发布时间:2026-01-12

点击量:
async/await 是 Promise 的语法封装,不能替代 Promise;async 函数自动返回 Promise,await 只能在 async 函数内使用,会暂停当前函数但不阻塞主线程,错误需用 try/catch 捕获。

async/await 不是新语法糖,而是 Promise 的语法封装;它不能替代 Promise,但能让异步流程像同步代码一样可读、可调试。

async 函数必须返回 Promise

声明一个 async 函数时,JavaScript 引擎会自动把它包装成返回 Promise 的函数——哪怕你 return 42,实际返回的是 Promise.resolve(42)

  • 如果函数内抛出错误(throw new Error()),等价于返回 Promise.reject()
  • 不能用 return await somePromise() 包裹顶层调用,这多一层不必要的等待;直接 return somePromise() 更高效
  • async 函数内部仍需用 try/catch 捕获 await 的异常,而不是靠外层 .catch()
async function fetchUser() {
  try {
    const res = await fetch('/api/user');
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return await res.json();
  } catch (err) {
    console.error('Failed to fetch user:', err.message);
    throw err; // 保持 reject 链路清晰
  }
}

await 只能在 async 函数内使用

这是常见报错源头:await is only valid in async functions。它不是独立语句,而是 async 函数的专属操作符。

  • 不能在普通函数、事件回调(如 addEventListener)、模块顶层直接写 await
  • 想在模块顶层用?ES2025 起支持 top-level await,但仅限 ES 模块(type="module"),且会影响模块初始化顺序
  • Node.js 中需加 --experimental-top-level-await(v14.8+ 默认启用),但生产环境慎用,尤其涉及依赖顺序时

await 会阻塞当前 async 函数,但不阻塞主线程

很多人误以为 await 会让整个 JS 线程卡住。其实它只是暂停当前 async 函数的执行,把控制权交还给事件循环,其他任务(如点击事件、定时器)照常运行。

  • 连续 await 是串行的:多个请求依次发起,总耗时 ≈ 各请求耗时之和
  • 想并发?用 Promise.all([p1, p2, p3]) 包裹后 await,总耗时 ≈ 最慢那个请求
  • await Promise.allSettled([...]) 更稳妥,即使某个请求失败也不中断其余请求
async function loadAll() {
  // ❌ 串行:3 秒 + 2 秒 + 1 秒 = ~6 秒
  const a = await fetch('/a');
  const b = await fetch('/b');
  const c = await fetch('/c');

  // ✅ 并发:~3 秒(最长那个)
  const [a, b, c] = await Promise.all([
    fetch('/a'),
    fetch('/b'),
    fetch('/c')
  ]);
}

错误处理容易漏掉 try/catch 或忽略 rejected promise

最常被忽视的点:没包 try/catch,又没接 .catch(),导致未捕获异常(unhandledrejection)。

  • await 后面的 Promise 被 reject,若没 try/catch,会触发全局 unhandledrejection 事件
  • 在 Node.js 中这会导致进程退出(除非监听了 process.on('unhandledRejection')
  • 浏览器中虽不崩溃,但控制台报错,且后续逻辑中断
  • 不要写 await someAsyncFn().catch(...) —— 这样 await 等到的是 undefinedcatch 返回值,语义混乱

真正该做的是:始终用 try/catch 包住每个需要容错的 await 表达式,或明确用 .catch() 处理并返回默认值。

标签:# javascript  # java  # js  # node.js  # json  # node  # 浏览器  # ai  # 点击事件  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!