【问题标题】:How could I use Promise.all in an Async/Await function using try/catch我如何在使用 try/catch 的 Async/Await 函数中使用 Promise.all
【发布时间】:2021-08-14 02:14:20
【问题描述】:

我正在努力理解承诺。到目前为止,我喜欢使用 async/await 和 try/catch 块,因为它对我个人来说是可读的。

但是我坚持使用Promise.all

这是我用来练习的数据。

const starWars = [
  'https://swapi.co/api/people/1',
  'https://swapi.co/api/people/2',
  'https://swapi.co/api/people/3',
  'https://swapi.co/api/people/4'
];

我觉得我必须在 async 函数中使用 .map() 但总是遇到错误。

所以我的问题是。使用 async/await、Promise.all 和 try/catch 块从这些 url 获取数据的方法是什么?

【问题讨论】:

    标签: javascript ecmascript-6


    【解决方案1】:

    将每个 URL 映射到 fetch 调用,并在 fetch Promise 上调用 .json

    const urls = [
      'https://swapi.co/api/people/1',
      'https://swapi.co/api/people/2',
      'https://swapi.co/api/people/3',
      'https://swapi.co/api/people/4'
    ];
    
    (async () => {
      try {
        const allResponses = await Promise.all(
          urls.map(url => fetch(url).then(res => res.json()))
        );
        console.log(allResponses[0]);
      } catch(e) {
        console.log(e);
        // handle errors
      }
    })();

    我更喜欢在函数之外捕获,我认为它看起来更干净并且需要更少的缩进:

    const urls = [
      'https://swapi.co/api/people/1',
      'https://swapi.co/api/people/2',
      'https://swapi.co/api/people/3',
      'https://swapi.co/api/people/4'
    ];
    
    (async () => {
      const allResponses = await Promise.all(
        urls.map(url => fetch(url).then(res => res.json()))
      );
      console.log(allResponses[0]);
      // do stuff with allResponses
    })()
      .catch((e) => {
        console.log(e);
        // handle errors
      });

    如果你只有一个地方需要等待 Promise 解决,你也可以考虑完全放弃 async 函数(这看起来更好 IMO):

    const urls = [
      'https://swapi.co/api/people/1',
      'https://swapi.co/api/people/2',
      'https://swapi.co/api/people/3',
      'https://swapi.co/api/people/4'
    ];
    
    Promise.all(
      urls.map(url => fetch(url).then(res => res.json()))
    )
      .then((allResponses) => {
        console.log(allResponses[0]);
        // do stuff with allResponses
      })
      .catch((e) => {
        console.log(e);
        // handle errors
      });

    【讨论】:

    • 你为什么还要在第二个中使用async/await?为什么要使用IIFE?为什么不把.then().catch() 放在Promise.all() 的promise 上,让代码看起来更简单?
    • 是的,我不认为async/await 在只有一个地方可以等待时有任何好处,但这就是 OP 试图弄清楚如何实施的原因跨度>
    【解决方案2】:

    您可以使用map 函数为所有网址创建承诺,并通过Promise.all 等待它们

    const starWars = [
      'https://swapi.co/api/people/1',
      'https://swapi.co/api/people/2',
      'https://swapi.co/api/people/3',
      'https://swapi.co/api/people/4'
    ]; 
    
    const promises = starWars.map(url => fetch(url).then(res => res.json());
    
    Promise.all(promises).then(results => /*Resolved code*/)
                         .catch(error => /*Rejected code*/);
    

    【讨论】:

      【解决方案3】:
      const starWars = [
        'https://swapi.co/api/people/1',
        'https://swapi.co/api/people/2',
        'https://swapi.co/api/people/3',
        'https://swapi.co/api/people/4'
      ];
      
      async function makeApiCalls() {
        try {
          let res = await Promise.all(starWars.map(endpoint => fetch(endpoint)));
          // depending on content-type apply .json() .blob() etc
          console.log(response);
        } catch (err) {
          console.error(err);
        }
      }
      
      

      【讨论】:

        【解决方案4】:

        我也遇到了同样的问题,Discord 的一位导师帮助了我。

        我相信您在 Windows 10 上运行它,而我所做的只是关闭了安全性(在 chrome 的隐私和安全设置中)并且它按预期工作。

        注意:请务必在浏览时开启此功能。

        【讨论】:

          猜你喜欢
          • 2023-01-17
          • 2021-08-28
          • 2019-09-30
          • 2017-11-23
          • 2018-10-17
          • 2018-12-26
          相关资源
          最近更新 更多