信息发布→ 登录 注册 退出

什么是Javascript的async和await_如何用Javascript async/await简化异步编程?

发布时间:2026-01-02

点击量:
async/await 是 Promise 的语法封装而非新语法糖,它通过自动包装返回值为 Promise、暂停执行而不阻塞主线程、强制 try/catch 错误处理及需配合 Promise.all 实现并发等机制,简化异步流程但不改变事件循环本质。

async/await 不是新语法糖,而是 Promise 的语法封装;它不能替代 Promise,但能显著降低回调嵌套和错误处理的复杂度。

async 函数本质是返回 Promise 的函数

声明一个 async 函数,等价于手动包装一个返回 Promise 的函数。调用它总会得到一个 Promise 实例,哪怕你 return 42,它也会被自动包装成 Promise.resolve(42)

常见误解:以为 async 让函数“变同步”了——其实它只是让 await 可以暂停函数执行(仅限当前函数体),底层仍是事件循环驱动。

  • async 函数内部遇到 await 会暂停,把控制权交还给事件循环,不阻塞主线程
  • 如果 await 后面不是 Promise,会自动用 Promise.resolve() 包装
  • 函数内抛出异常,等价于返回 Promise.reject(err)

await 只能在 async 函数内部使用

直接在顶层或普通函数里写 await 会报 SyntaxError: await is only valid in async functions。这是语法限制,不是运行时错误。

常见场景应对方式:

  • 模块顶层需等待:用 (async () => { ... })() 立即执行
  • 事件处理器中:把 handler 声明为 async function handleClick() { ... }
  • 循环中逐个 await:注意这会串行执行;想并发请用 Promise.all([p1, p2, p3])
async function fetchUsers() {
  try {
    const res = await fetch('/api/users');
    const users = await res.json();
    return users;
  } catch (err) {
    console.error('Fetch failed:', err);
    throw err;
  }
}

错误处理必须用 try/catch,不能只靠 .catch()

await 后的 Promise 被 reject,会直接抛出异常,不会像 .then().catch() 那样隐式传递。漏写 try/catch 就会导致未捕获异常(Uncaught (in promise))。

特别注意:

  • await Promise.reject('oops') 会立即触发 catch 块,不是“跳过后续代码”而是中断当前 async 函数执行流
  • 多个 await 连续写时,任一失败都会终止后续 await,除非你对每个都单独 try/catch
  • 想忽略某个请求失败?得显式写 await something().catch(() => {}) 或用空数组兜底

await 处理并发请求:别误用 for 循环

for (const url of urls) { await fetch(url); } 是串行请求,总耗时 ≈ 所有请求时间之和。真正并发要先发所有请求,再统一 await。

正确做法:

  • 并发全部发起:const promises = urls.map(u => fetch(u))
  • 等全部完成:const responses = await Promise.all(promises)
  • 若允许部分失败,用 Promise.allSettled() 替代 Promise.all()
async function fetchAll(urls) {
  const promises = urls.map(url => 
    fetch(url).then(r => r.json()).catch(() => null)
  );
  return await Promise.all(promises);
}

最易被忽略的一点:await 不会“等整个异步链”,它只等紧跟着的那个 Promise 完成。如果你忘了链式调用中某处没 return,后续 await 就可能等错对象——比如漏了 return 导致 await 等到 undefined,再被包装成已 resolve 的 Promise,逻辑就悄悄跑偏了。

标签:# javascript  # java  # js  # json  # 处理器  # ai  # 并发请求  
在线客服
服务热线

服务热线

4008888355

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

截屏,微信识别二维码

打开微信

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