找回密码
 立即注册
首页 业界区 安全 async/await简单理解

async/await简单理解

拍棹 昨天 02:40
一、async/await 是什么?

async/await 是 ES2017(ES8)引入的异步编程语法糖,基于 Promise 实现,目的是让异步代码的写法更接近同步代码,降低阅读和编写成本。核心概念拆解:


  • async 关键字

    • 只能修饰函数(函数声明、函数表达式、箭头函数都可以)。
    • 被 async 修饰的函数,返回值一定是 Promise 对象:

      • 如果函数内部返回非 Promise 值(比如数字、字符串),会自动被包装成 resolve 状态的 Promise;
      • 如果函数内部抛出错误,会返回 reject 状态的 Promise;
      • 如果函数内部返回 Promise,则直接返回这个 Promise。


  • await 关键字

    • 只能在 async 函数内部使用,不能单独使用。
    • 作用:等待右侧的 Promise 完成(状态变为 resolve 或 reject),并暂停当前 async 函数的执行,直到 Promise 有结果:

      • 如果 Promise 是 resolve 状态,await 会返回 Promise 的成功值;
      • 如果 Promise 是 reject 状态,await 会抛出错误,需要用 try/catch 捕获。 


二、为什么要用 async/await?

核心原因:解决传统回调地狱、简化 Promise 链式调用的复杂度。我们通过对比来理解:场景:模拟异步请求(比如先请求用户信息,再根据用户 ID 请求订单)

1. 回调函数写法(回调地狱)
  1. // 模拟异步请求函数
  2. function getUserInfo(callback) {
  3.   setTimeout(() => {
  4.     callback(null, { id: 1, name: "张三" });
  5.   }, 1000);
  6. }
  7. function getOrderByUserId(userId, callback) {
  8.   setTimeout(() => {
  9.     callback(null, { orderId: 1001, userId: userId });
  10.   }, 1000);
  11. }
  12. // 调用:多层嵌套,代码臃肿,可读性差
  13. getUserInfo((err, user) => {
  14.   if (err) return console.error(err);
  15.   getOrderByUserId(user.id, (err, order) => {
  16.     if (err) return console.error(err);
  17.     console.log("订单信息:", order);
  18.   });
  19. });
复制代码
2. Promise 写法(改善但仍有链式冗余)
  1. function getUserInfo() {
  2.   return new Promise((resolve) => {
  3.     setTimeout(() => resolve({ id: 1, name: "张三" }), 1000);
  4.   });
  5. }
  6. function getOrderByUserId(userId) {
  7.   return new Promise((resolve) => {
  8.     setTimeout(() => resolve({ orderId: 1001, userId: userId }), 1000);
  9.   });
  10. }
  11. // 调用:链式调用,比回调好,但仍有.then 嵌套,逻辑不连贯
  12. getUserInfo()
  13.   .then(user => getOrderByUserId(user.id))
  14.   .then(order => console.log("订单信息:", order))
  15.   .catch(err => console.error(err));
复制代码
3. async/await 写法(简洁如同步)
  1. function getUserInfo() {
  2.   return new Promise((resolve) => {
  3.     setTimeout(() => resolve({ id: 1, name: "张三" }), 1000);
  4.   });
  5. }
  6. function getOrderByUserId(userId) {
  7.   return new Promise((resolve) => {
  8.     setTimeout(() => resolve({ orderId: 1001, userId: userId }), 1000);
  9.   });
  10. }
  11. // 核心:async 函数 + await 等待异步结果
  12. async function getOrderInfo() {
  13.   try {
  14.     // 等待 getUserInfo 完成,拿到用户信息(同步写法)
  15.     const user = await getUserInfo();
  16.     // 等待 getOrderByUserId 完成,拿到订单信息
  17.     const order = await getOrderByUserId(user.id);
  18.     console.log("订单信息:", order);
  19.   } catch (err) {
  20.     // 统一捕获所有异步错误
  21.     console.error(err);
  22.   }
  23. }
  24. // 执行函数
  25. getOrderInfo();
复制代码
三、async/await 的核心优势


  • 代码可读性极高:异步逻辑按 “从上到下” 的同步顺序书写,无需嵌套或链式调用,新手也能快速理解。
  • 错误处理更统一:用 try/catch 捕获所有异步错误(包括 Promise 的 reject),替代 Promise 的多个 .catch。
  • 调试更友好:可以像同步代码一样打断点,逐行调试(Promise 链式调用调试时难以追踪执行顺序)。
  • 支持顺序 / 并行执行:

    • 顺序执行:如上例,await 依次等待,适合依赖前一个结果的场景;
    • 并行执行:如果异步操作无依赖,可先用变量存储 Promise,再一起 await,提升性能:

  1. async function getMultiData() {
  2.   // 先创建两个 Promise(立即执行异步操作)
  3.   const userPromise = getUserInfo();
  4.   const orderPromise = getOrderByUserId(1); // 假设 ID 已知,无需等用户信息
  5.   // 并行等待两个 Promise 完成
  6.   const [user, order] = await Promise.all([userPromise, orderPromise]);
  7.   console.log(user, order);
  8. }
复制代码
总结


  • async/await 是 Promise 的语法糖,不改变异步本质,只是让异步代码写法更简洁;
  • async 修饰函数,使其返回 Promise;await 只能在 async 函数内使用,等待 Promise 结果并暂停函数执行;
  • 核心价值:解决回调地狱、简化 Promise 链式调用,让异步代码的阅读 / 编写 / 调试成本大幅降低。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册