【问题标题】:How to perform an action once nested fetch-es are complete?嵌套的 fetch-es 完成后如何执行操作?
【发布时间】:2019-11-07 04:30:05
【问题描述】:

下面的代码从 API 中获取一个数组,然后为该数组的每个元素检索更多数据。

fetch('https://reqres.in/api/users')
  .then(r => r.json()).then(r => {
    r.data.forEach(x => {
      fetch('https://reqres.in/api/users')
        .then(r => r.json()).then(r => {
          r.data.forEach(x => console.log(x.id))
        })
    })
  })

一旦完全检索到数据,我需要对其执行一些操作。该怎么做?

问题在于这是一组异步解决的 Promise。 Promise.all() 可用于收集所有 Promise 并从那里开始工作 - 但它们的数量是未知的。换句话说,我可以使用

a = fetch('https://reqres.in/api/users')
b = fetch('https://reqres.in/api/users')
Promise.all([a, b]).then(x => console.log('all resolved here'))

但是脚本启动时传递给Promise.all() 的内容是未知的。

【问题讨论】:

    标签: javascript promise es6-promise fetch-api


    【解决方案1】:

    也许这将是解决方案,但您的方法似乎有问题。

    fetch('https://reqres.in/api/users')
      .then(r => r.json()).then(r => {
        return Promise.all(r.data.map(x => {
          return fetch('https://reqres.in/api/users')
            .then(r => r.json()).then(r => {
              r.data.forEach(x => console.log(x.id))
            })
          )
        })
      })
    

    换句话说,您可以使用嵌套的 Promise.all 并将其作为执行 thens 的内部代码的结果返回。还有一个重要注意事项,您应该使用 map 而不是 forEach 进行迭代异步调用。

    【讨论】:

      【解决方案2】:

      您可以使用Array.map 做出一系列承诺:

      const allPromises = r.data.map(x => {
        return fetch('https://reqres.in/api/users/' + x)
          .then(r => r.json())
      });
      
      Promise.all(allPromises).then(data => console.log('All data is loaded', data))
      

      【讨论】:

        【解决方案3】:

        ...但是脚本启动时传递给 Promise.all() 的内容是未知的。

        没关系,你可以用map代替forEach然后等待结果:

        fetch('https://reqres.in/api/users')
          .then(r => r.json()).then(r =>
            Promise.all(r.data.map(x =>
              fetch('https://reqres.in/api/users') // (presumably there's some parameter here, you're not just repeating the same call...)
                .then(r => r.json())
                .then(r => {
                  r.data.forEach(x => console.log(x.id))
                })
            ))
          );
        

        map 中创建的所有承诺都解决或其中任何一个被拒绝之前,上述返回的链不会结算。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-09-28
          • 1970-01-01
          • 2020-11-15
          • 1970-01-01
          • 2019-05-17
          • 2015-05-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多