如何避免陷入async/await地狱?

什么是async/await地狱

在JavaScript中,async/await语法为我们处理异步代码提供了一种更直观、更易读的方式,如果滥用或不正确使用,可能会导致“async/await地狱”,即代码变得冗长且难以维护,这种情况通常发生在开发者将每个异步操作都串行化,即使这些操作本可以并行执行。

async/await地狱的示例

async/await地狱避免

假设我们要编写一个购买披萨和饮料的程序,以下是一个典型的async/await地狱的例子:

(async () => {
  const pizzaData = await getPizzaData();    // 获取披萨列表(异步调用)
  const drinkData = await getDrinkData();    // 获取饮料列表(异步调用)
  const chosenPizza = choosePizza();          // 选择披萨(同步调用)
  const chosenDrink = chooseDrink();          // 选择饮料(同步调用)
  await addPizzaToCart(chosenPizza);         // 将选中的披萨加入购物车(异步调用)
  await addDrinkToCart(chosenDrink);         // 将选中的饮料加入购物车(异步调用)
  orderItems();                             // 确认订单(异步调用)
})();

这段代码虽然能够运行,但并不是一个好的实现方式,问题在于,所有的代码都是一行接着一行执行的,没有任何并发执行的情况,为什么在获取饮料列表之前需要等待披萨列表的返回?我们应该尝试同时获取饮料和披萨的列表。

如何避免async/await地狱

找出所有依赖其他代码来执行的代码

在我们的例子中,选择披萨和饮料的操作是相互独立的,可以并行进行,我们可以将这些操作分成不同的异步函数,并利用Promise.all()方法来并发执行它们。

把相互依赖执行的语句整合在异步函数里面

选择披萨需要以下几个互相依赖的语句:获取披萨列表、选择其中一个披萨以及添加到购物车中,我们应该把这些语句整合在一个异步函数里面,同样地,选择饮料的操作也放在另一个异步函数里。

并发的执行这些异步函数

async/await地狱避免

我们将利用事件循环的优势来并发地执行这些非阻塞异步函数,常用的方法是先返回Promise然后使用Promise.all()方法。

修改后的代码示例

async function selectPizza() {
  const pizzaData = await getPizzaData();    // 获取披萨列表(异步调用)
  const chosenPizza = choosePizza();          // 选择披萨(同步调用)
  await addPizzaToCart(chosenPizza);         // 将选中的披萨加入购物车(异步调用)
}
async function selectDrink() {
  const drinkData = await getDrinkData();    // 获取饮料列表(异步调用)
  const chosenDrink = chooseDrink();          // 选择饮料(同步调用)
  await addDrinkToCart(chosenDrink);         // 将选中的饮料加入购物车(异步调用)
}
(async () => {
  const [pizzaPromise, drinkPromise] = Promise.all([selectPizza(), selectDrink()]);
  await pizzaPromise;
  await drinkPromise;
  orderItems();                             // 确认订单(异步调用)
})();

在这个修改后的示例中,我们首先定义了两个异步函数selectPizzaselectDrink,分别负责选择披萨和饮料的相关操作,在主函数中使用Promise.all()方法并发地执行这两个异步函数,最后等待它们完成并确认订单,这样不仅提高了代码的性能,还使其更加清晰易读。

相关问题与解答

问题1:如果我们忘记了await关键字会怎样?

如果在调用异步函数时忘记使用await关键字,这意味着函数开始执行了,但不会等待其完成,异步函数会返回一个Promise对象,这个Promise可以在之后被解析,另一个后果是编译器不知道你需要等待这个函数执行完成,因此编译器可能会在异步任务还没有完成的时候退出程序,我们需要使用await关键字来确保程序在适当的时候等待异步函数完成。

问题2:如何在多个异步操作之间实现并发执行?

要在多个异步操作之间实现并发执行,可以使用Promise.all()方法,这个方法接受一个包含多个Promise对象的数组作为参数,并返回一个新的Promise,当所有的输入Promise都成功解决时,新的Promise也会成功解决,并且解决的值是一个包含所有输入Promise解决值的数组,通过这种方式,我们可以并发地执行多个异步操作,而不需要等待前一个操作完成再进行下一个操作。

以上就是关于“async/await地狱避免”的问题,朋友们可以点击主页了解更多内容,希望可以够帮助大家!

原创文章,作者:K-seo,如若转载,请注明出处:https://www.kdun.cn/ask/645120.html

Like (0)
Donate 微信扫一扫 微信扫一扫
K-seo的头像K-seoSEO优化员
Previous 2024-11-16 00:26
Next 2024-11-16 00:28

相关推荐

  • 如何使用AsyncJS实现高效的并行查询操作?

    一、概述在JavaScript中,async/await语法提供了一种简洁且直观的方式来处理异步操作,通过将异步操作包装在Promise对象中,并使用async和await关键字,我们可以像编写同步代码一样编写异步代码,这使得代码更加可读和易于维护,二、Async.js并行查询1. 基本概念串行与并行:串行执行……

    2024-11-16
    00
  • linux中线程是什么意思(linux中的线程)

    在Linux中,线程是进程的执行单元,它是CPU调度和分配的基本单位。一个进程可以包含多个线程,它们共享进程的资源,如内存、文件描述符等。

    2024-04-30
    0178
  • 如何有效避免async/await地狱?详解来啦!

    async/await地狱该如何避免详解在现代JavaScript开发中,async/await语法为我们提供了一种更简洁、直观的方式来处理异步操作,如果使用不当,它可能会导致所谓的“async/await地狱”,即代码中充斥着大量的await语句,使得代码变得难以阅读和维护,本文将详细解释什么是async/a……

    2024-11-15
    00

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

免备案 高防CDN 无视CC/DDOS攻击 限时秒杀,10元即可体验  (专业解决各类攻击)>>点击进入