嵌套的 fetch-es 完成后如何执行操作?

Posted

技术标签:

【中文标题】嵌套的 fetch-es 完成后如何执行操作?【英文标题】:How to perform an action once nested fetch-es are complete? 【发布时间】: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() 的内容是未知的。

【问题讨论】:

【参考方案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 中创建的所有承诺都解决或其中任何一个被拒绝之前,上述返回的链不会结算。

【讨论】:

以上是关于嵌套的 fetch-es 完成后如何执行操作?的主要内容,如果未能解决你的问题,请参考以下文章

两个嵌套for循环的执行顺序

redux thunk - 承诺完成后如何在嵌套数组中调度数据

如何在 Ionic 3 中执行多个异步操作并在一切完成后关闭加载器?

如何等待ajax完成再执行相应操作

如何避免嵌套事务不支持错误?

如何在不使用完成块的情况下在动画后执行代码?