在 React 中使用 Async/Await 处理嵌套 Promise

发布日期:2026-07-03 21:07:02   来源 : 杭州电子商务研究院    浏览量 :10
杭州电子商务研究院 发布日期:2026-07-03 21:07:02  
10

介绍

异步代码总是会带来认知开销。人类的思维可能习惯于同步思考,因此试图理解异步代码似乎是一件令人望而生畏的事情。多年来,已经出现了许多试图缓解这种复杂性的构造。长期以来,在 JavaScript 代码中模拟异步的唯一方法是通过回调。回调的问题在于它们会在您的应用程序中留下一串“意大利面条式”代码——您可能熟悉“回调地狱”这个术语。

现代 JavaScript 引入了一种建模异步代码的新方法:Promises。Promises 使 JavaScript 和 React 开发人员能够编写无需回调的异步代码 - 但是,在旧样式中嵌套 Promises 仍然很容易,这会导致代码难以阅读。

现代 JavaScript 中引入的新 async/await 关键字旨在通过在承诺之上提供“语法糖”来解决此问题。在本指南中,您将学习如何利用 async/await 来简化 React 应用中的嵌套承诺。您将看到如何不仅可以将编写的异步代码量减少一半,还可以消除所涉及的大部分心理复杂性。您将看到 async/await 语法如何让您以同步方式推理异步代码。

让我们开始吧。

问题概述:嵌套 Promises

以下列方式编写的代码并不罕见。下面,您可以看到一些典型的异步代码,它们使用嵌套承诺来发出连续的 HTTP 请求以获取“炸鱼和薯条”。大多数情况下,您会看到这样编写的代码的原因是,这通常是您编写异步代码的第一直觉。

      // my-component.jsx

// We have to get chips after we get fish...
getFishAndChips = () => {
    fetch(this.fishApiUrl) // Request fish
        .then(fishRes => {
            fishRes.json().then(fish => {
                this.fish = fish;

                const fishIds = fish.map(fish => fish.id);

                fetch( // Request chips using fish ids
                        this.chipsApiUrl,
                        {
                            method: 'POST',
                            body: JSON.stringify({ fishIds })
                        }
                    )
                    .then(chipsRes => {
                        chipsRes.json().then(chips => {
                            this.chips = chips;
                        })
                    })
            })
        })
}
    

上面的代码嵌套了两个fetch调用,以确保您在请求鱼之后请求薯条。这是因为,为了请求薯条,您需要使用 POST 请求发送鱼 ID 数组。这可以行得通,但是这里有一个巨大的可读性问题。编写上述代码就像是用回调地狱换取……承诺地狱!谁想这样做!?可以大大减少此功能所需的代码量。让我们来看看承诺链!

临时解决方案:Promise Chaining

消除这些fetch调用嵌套的第一种方法是使用所谓的 Promise 链。只需在Promise.then调用中返回另一个 Promise 即可实现 Promise 链。以下示例显示了如何执行此操作:

      // We have to get chips after we get fish...
getFishAndChips = () => {
    fetch(this.fishApiUrl) // Request fish
        .then(response => response.json())
        .then(fish => {
            this.fish = fish;

            const fishIds = fish.map(fish => fish.id);

            return fetch( // Request chips using fish ids
                        this.chipsApiUrl,
                        {
                            method: 'POST',
                            body: JSON.stringify({ fishIds })
                        }
                    );
        })
        .then(response => response.json())
        .then(chips => {
            this.chips = chips;
        });
}
    

这太棒了!代码更易于维护、简洁且易读。但我们可以做得更好!借助 JavaScript 中引入的新 async/await 语法,我们可以完全消除对Promise.then的多次调用!您将在下一节中看到如何实现这一点。

最佳解决方案:Async/Await

async/await 关键字是一种在计算机程序中建模异步控制流的绝妙机制。在 JavaScript 中,这些关键字是 Promises 之上的语法糖 — 它们抽象出对Promise.then的调用。在下面的代码中,我们重构getFishAndChips函数以使用 async/await。

      // We have to get chips after we get fish...
getFishAndChips = async () => {
    const fish = await fetch(this.fishApiUrl).then(response => response.json());

    const fishIds = fish.map(fish => fish.id),
    chipReqOpts = { method: 'POST', body: JSON.stringify({ fishIds }) };

    const chips = await fetch(this.chipsApiUrl, chipReqOpts).then(response => response.json());
}
    

哇!将第一部分的第一个代码片段与此代码进行比较。差别太大了!我们大大压缩了所使用的代码,同时实现了相同的效果。此代码更易于阅读和维护。您可以轻松看到,通过能够以同步方式推理代码,可以减少多少思维复杂性 - 无需嵌套!只需使用 async 关键字标记您的异步函数即可这使您可以使用await关键字为您解决承诺!控制流的 async/await 机制是一种非常强大的方式,可以推理应用程序内的任何异步内容。

结论

在应用中编写链式异步操作序列可能很困难。嵌套承诺是实现此操作的一个不幸的副产品。但值得庆幸的是,正如您在本指南中看到的那样,通过承诺链或 async/await 语法可以轻松避免和/或重构嵌套承诺。在这两种解决方案中,最易读的代码是使用 async/await 语法编写的,因此请努力在您自己的应用中使用它!

现在,您可以自信地在 React 组件中编写现代且可读的异步代码!有关更多信息,请查看async/await 语法的文档。

以上内容来自杭州电子商务研究院推送
关注
关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 关注 数据