什么是async/await?什么时候用async/await?——用生活中的例子彻底搞懂

一、什么是async/await?——快餐店里的“聪明服务员”

1.1 同步与异步的本质区别

想象你去快餐店点餐:

  • 同步:你站在柜台前,​死死盯着厨师煎汉堡,直到汉堡做好才能点饮料。这期间队伍后面的人只能干等(就像浏览器卡死)。
  • 异步:你点完汉堡后拿到一个取餐号,转身去选座位、玩手机、拿饮料,​听到叫号再回来取餐​(这就是异步非阻塞)。

async/await 就是帮你优雅管理取餐号的工具!

1.2 代码中的async/await长什么样?


javascript

// 普通函数(同步)
function makeCoffee() {
  grindBeans();    // 磨咖啡豆(耗时)
  brewCoffee();    // 冲泡咖啡(耗时)
  return "卡布奇诺";
}

// async函数(异步)
async function makeCoffeeAsync() {
  await grindBeansAsync(); // 等磨豆机完成
  await brewCoffeeAsync(); // 等咖啡机完成
  return "冰美式";
}

关键区别:async函数中可以用await暂停等待,但不阻塞主线程​(就像服务员不等咖啡机,先去擦桌子)。


二、什么时候用async/await?——4大典型场景

2.1 场景1:网络请求(就像“等外卖”)

  • 传统写法​(回调地狱):
    
    

    javascript

    fetchData("/api/user", (user) => {
      fetchData("/api/orders", (orders) => {
        renderPage(user, orders); // 嵌套层级越来越深
      });
    });
  • async/await写法
    
    

    javascript

    async function loadPage() {
      const user = await fetch("/api/user");
      const orders = await fetch("/api/orders");
      renderPage(user, orders); // 代码像从上到下阅读一样简单
    }

类比:服务员先下单外卖,在等餐时去服务其他顾客,外卖到了再回来处理。


2.2 场景2:文件操作(就像“用洗衣机”)

  • 问题:读取大文件时会卡住整个程序。
  • async解决方案
    
    

    javascript

    async function processFile() {
      const data = await fs.readFile("report.pdf"); // 异步读取
      const compressed = await compress(data);      // 异步压缩
      await uploadToCloud(compressed);              // 异步上传
    }

类比:把衣服丢进洗衣机后,你去扫地、叠被子,洗衣机“滴滴”响了你再晾衣服。


2.3 场景3:定时任务(就像“煮泡面”)

  • 传统写法
    
    

    javascript

    setTimeout(() => {
      console.log("3分钟到了");
      startNextStep(); // 需要嵌套回调
    }, 3000);
  • async写法
    
    

    javascript

    async function cookInstantNoodles() {
      await wait(3000); // 等待3分钟
      addSeasoning();   // 加调料
      await wait(120);  // 再等2分钟
      eat();            // 开吃!
    }

类比:定好闹钟后,你可以去切火腿肠、刷手机,闹钟响了再继续下一步。


2.4 场景4:并行任务(就像“多线程做饭”)


javascript

async function cookDinner() {
  // 同时开火煮汤和炒菜(并行)
  const soupPromise = boilSoup();    // 不await,直接拿到Promise
  const stirFryPromise = stirFry();  // 另一个Promise

  // 等两个任务都完成
  const [soup, stirFry] = await Promise.all([soupPromise, stirFryPromise]);
  
  serveDinner(soup, stirFry); // 上菜
}

类比:厨师同时开两个灶台,汤锅和炒锅一起做,最后一起出锅。


三、使用async/await的3个原则

3.1 原则1:​不滥用await

  • 错误示范
    
    

    javascript

    async function foo() {
      await task1(); // 不必要的await
      await task2(); // 实际需要并行执行
    }
  • 正确做法:无关的任务用Promise.all并行处理。

3.2 原则2:​统一错误处理


javascript

async function fetchData() {
  try {
    const data = await fetch("/api");
    return data;
  } catch (error) {
    console.log("网络开小差了,刷新重试吧!");
  }
}

类比:服务员发现汉堡做糊了,立刻道歉并重做,而不是让顾客干等。

3.3 原则3:​理解底层原理

  • async函数本质是返回Promise
    
    

    javascript

    async function foo() { return 123; }
    // 等价于
    function foo() { return Promise.resolve(123); }
  • await本质是暂停函数执行,直到Promise状态变化。

四、总结:为什么async/await是必学技能?

  1. 消灭回调地狱:代码从“金字塔形”变“扁平化”。
  2. 错误处理更直观:用try/catch替代.then().catch()
  3. 符合人类直觉:像写同步代码一样思考异步流程。

终极类比
async/await就像给你的代码配了一个私人助理,你说“等这份文件下载完告诉我”(await),助理默默在后台等待,期间帮你处理邮件、接电话,文件一到立刻提醒你继续工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值