了解 Promise.all 和 Array.map()

Posted

技术标签:

【中文标题】了解 Promise.all 和 Array.map()【英文标题】:Understanding Promise.all and Array.map() 【发布时间】:2021-07-10 18:32:42 【问题描述】:

我正在从多个 API 检索数据,这些数据将被聚合到一个最终数组中,我打算在其中映射并显示在 UI 中(使用 React)。所以为了更好的上下文,我有这种情况。

首先我从主 API 检索主要数据

const response = await getFirstData() // returns an array

const [secondResult, thirdResult, fourthResult] = await Promise.all([
 response.map(async (item) => await secondApiRequest()),
 response.map(async (item) => await thirdApiRequest()),
 response.map(async (item) => await fourthApiRequest())
])

从上面可以看出,基于主 API 中的response,然后我映射返回的数组以从其他 API 中获取数据(secondApiRequest(), etc..)。现在我在想secondResultthirdResultfourthResult 将解析为应有的对象数组。但是当我在 chrome 浏览器上查看日志时,却看到了这个。

0: Promise <fulfilled>: Array(10)
1: Promise <fulfilled>: Array(10)
2: Promise <fulfilled>: Array(10)
3: Promise <fulfilled>: Array(10)
4: Promise <fulfilled>: Array(10)
5: Promise <fulfilled>: Array(5)
6: Promise <fulfilled>: Array(0)
7: Promise <fulfilled>: Array(0)
8: Promise <fulfilled>: Array(0)
9: Promise <fulfilled>: Array(0)

我知道这些操作是并行运行的,但是如何让这些操作解析并返回应该包含对象的最终数组。此外,实现这一目标的最有效方法是什么,因为 finalArray 最后将包含 200 多个对象,我必须在 UI 上显示它们。谢谢,欢迎任何帮助。

【问题讨论】:

你能澄清一下你想在这里发生什么@thatkingguy_?如果response 包含10 个项目,您是否希望secondApiRequest 被调用10 次?如果是这样,secondResult 应该是什么,与这 10 个 api 调用有关? @JamesMonger 所以response 是一个对象数组。我映射response 数组并对secondApiRequest 等进行其他调用,现在对于每个映射,我将id 传递给其他API 调用。例如response.map(async (item) =&gt; secondApiRequest(id))id参数是从response数组中的每个对象获取的。 【参考方案1】:

这允许您并行运行后续请求并在相应的变量中检索它们的结果:

const response = await getFirstData(); // returns an array

const [secondResult, thirdResult, fourthResult] = await Promise.all([
  Promise.all(response.map(item => secondApiRequest()),
  Promise.all(response.map(item => thirdApiRequest()),
  Promise.all(response.map(item => fourthApiRequest())
]);

【讨论】:

【参考方案2】:

如果你想并行发出所有请求,你应该返回一个 promise 数组给Promise.all()

为每个 api 映射响应,并使用 Promise.all() 等待它的承诺数组,然后使用外部调用等待所有内部 Promise.all() 调用。

const response = await getFirstData() // returns an array

const [secondResult, thirdResult, fourthResult] = await Promise.all(
  [secondApiRequest, thirdApiRequest, fourthApiRequest]
    .map(api => Promise.all(response.map(api)))
)

【讨论】:

这样做会使结果变平,并且不会在secondResultthirdResultfourthResult 变量中得到预期结果 谢谢。已更新。 另外我们也不知道response的items是否真的是每个后续请求的第一个参数 在这种情况下无关紧要。如果函数忽略item,则传递它并不重要。在您的情况下,如果您希望忽略该项目,您应该执行 () =&gt; secondApiRequest() 谢谢。也一样。

以上是关于了解 Promise.all 和 Array.map()的主要内容,如果未能解决你的问题,请参考以下文章

深入了解Promise

Promise.all() 与等待

Promise.all的异常处理,前端开发者需了解

Promise.all的异常处理,前端开发者需了解

Promise.all() 允许失败的替代方案? [复制]

对Promise的一些深入了解