当前位置: 首页 > 新闻动态 > 网络资讯

如何理解并使用javascript中的async和await?【教程】

作者:夜晨 浏览: 发布日期:2026-01-30
[导读]:async/await是Promise的语义封装,async函数自动返回Promise,await只能在async函数中等待thenable对象,需用try/catch捕获错误,并行用Promise.all,await不阻塞线程。
async/await 是 Promise 的语义封装,async 函数自动返回 Promise,await 只能在 async 函数中等待 thenable 对象,需用 try/catch 捕获错误,并行用 Promise.all,await 不阻塞线程。

async/await 不是新语法糖,而是 Promise 的语义封装;不用理解“事件循环”,先搞懂它怎么让异步代码像同步一样写、像 Promise 一样执行。

async 函数必须返回 Promise

声明一个 async 函数,哪怕你没写 await,它也自动把返回值包装成 Promise.resolve()

async function foo() {
  return 42;
}
foo(); // Promise {: 42}

这意味着你不能靠 return 直接跳出异步流程——想中断链式调用,得抛错或显式 return Promise.reject()

  • 返回原始值 → 自动转为 Promise.resolve(value)
  • 返回已存在的 Promise → 原样透传,不额外包装
  • 抛出异常 → 等价于 return Promise.reject(err)

await 只能在 async 函数里用,且只能等 thenable

await 不是万能等待器,它只接受“可等待对象”(thenable):即有 .then() 方法的对象,包括 Promise、Axios 响应、甚至手写的类 Promise 对象。

立即学习“Java免费学习笔记(深入)”;

常见误用:

  • await console.log('hi') → 报错:TypeError: console.log(...) is not a function(因为 console.log 返回 undefined,不是 thenable)
  • 在普通函数或顶层作用域写 await → 语法错误:Uncaught SyntaxError: await is only valid in async functions
  • await { then() {} } → 合法但危险:没有错误处理的空 then 会静默失败

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

await 后面的 Promise 被 reject,会直接抛出异常,跳过后续语句。你不能像链式调用那样在末尾统一 .catch()

async function bad() {
  const res = await fetch('/api');
  const data = await res.json();
  return data;
}
bad().catch(handleError); // ❌ 太晚了:如果 res.json() 报错,这里捕获不到

正确做法是每个可能失败的 await 都包进 try/catch,或至少在关键步骤后加一层:

  • 单个请求:用 try/catch 包住整个 await
  • 多个独立请求:可以并行 await Promise.all([p1, p2]),但错误会全量抛出,需提前预判哪些可容忍失败
  • 需要 fallback:用 await (promise.catch(() => defaultValue)),但注意这会让错误“消失”,调试时难定位

await 并不阻塞线程,只是暂停当前 async 函数执行

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

所以这两个例子行为不同:

// A:串行,总耗时 ≈ 1000 + 1000 = 2000ms
async function seq() {
  await sleep(1000);
  await sleep(1000);
}

// B:并行,总耗时 ≈ 1000ms
async function par() {
  const [a, b] = await Promise.all([sleep(1000), sleep(1000)]);
}

关键点在于:是否等待同一个 Promise 完成,而不是有没有写 await

容易被忽略的是:await 后面的表达式本身是同步求值的。比如 await foo() + bar()foo()bar() 都会立刻执行(如果它们不是异步的),只是等待 foo() 返回的 Promise sett

le。

免责声明:转载请注明出处:http://jing-feng.com.cn/news/769652.html

扫一扫高效沟通

多一份参考总有益处

免费领取网站策划SEO优化策划方案

请填写下方表单,我们会尽快与您联系
感谢您的咨询,我们会尽快给您回复!