如何处理单个数组上的多次异步调用?

问题描述 投票:0回答:1

这是一个比较理论性的问题。我原本想把这个问题叫做 能否对地图进行两次迭代?但听起来,这听起来像一个反模式。所以我想我只是方法不对。

另外注意:这里的数据作为一个抽象的服务器。我知道我在这里用这里提供的数据所做的事情是不必要的,但 请不要太过执着于数据结构。 和什么的。它并不能代表我正在处理的真实的(更复杂的,进一步说是由客户提供的,我不能改变的)数据。相反,我们可以把问题看作是 如何为每个数组项目返回结构化的异步调用。 拜托 :-)


我的问题归结起来是这样的。

  • 我有一个数组 id上,我需要执行两个独立的异步调用。
  • 这两个调用都需要通过(而且在所有的 id 实例)

所以作为一个例子,想象一下我有这两个数据集。

const dataMessages = [
  { id: "a", value: "hello" }, 
  { id: "b", value: "world" }
];

const dataNames = [
  { id: "a", name: "Samuel" },
  { id: "b", name: "John" },
  { id: "c", name: "Gustav"},
];

和一个API调用模拟。

const fetchFor = async (collection: Object[], id: string): Promise<Object> => {
  const user = collection.find(user => user.id === id);
  if (!user) {
    throw Error(`User ${id} not found`);
  }
  return user;
};

现在 我要打电话给... fetchFor() 函数,用于两个数据集,大概是在内部的内部。Promise.all,给定 forEach 并不是异步的,从预定的数组的 ids.

我在想类似于 map承诺清单 Promise.all 来执行。当你只需要映射一个api-call的时候,这很好用。

const run = async () => {
  const result = await Promise.all(
    ['a', 'b'].map(id => fetchFor(dataMessages, id)
  )
  console.log(result) // [{id: 'a', value: 'hello'}, {id: 'b', value: 'world}]
}

但是我需要同时返回两个承诺的代码

  • fetchFor(dataMessages, id)
  • fetchFor(dataNames, id)

里面 Promise.all 承诺数组。


我想我总是可以简单地做一个 flatMap 的两个映射的两个实例的API调用,但这听起来有点愚蠢,因为考虑到

  • 我会在同一个数组上做两次array.map。
  • 我的数据结构在逻辑上没有连接 (同一用户的两个独立的数组项目,甚至不会跟在对方后面)

所以,理想情况下,我希望返回数据的形式为

 const result = await Promise.all([...])
 console.log(result)
 /* [
 *   {id: 'a', message: 'hello', name: 'Samuel'},
 *   {id: 'b', message: 'world', name: 'John'},
 *  ]

还是说,我只需要做承诺的平面图,然后在解决的Promise.all上的一个单独的处理程序中,根据id标识符做数据合并到对象上?

我在这里提供了一个单api-call模拟的工作示例,所以你不必复制粘贴。

Edit zen-wildflower-480ig

对于这样的问题,正确的常用方法是什么?

javascript typescript asynchronous async-await es6-promise
1个回答
2
投票

你可以嵌套 Promise.all 的调用。

const [messages, names] = await Promise.all([
  Promise.all(
    ['a', 'b'].map(id => fetchFor(dataMessages, id)
  ),
  Promise.all(
    ['a', 'b', 'c'].map(id => fetchFor(dataNames, id)
  )
]);

如果你想在检索后合并结果 这只是一个标准的数据操作问题。

© www.soinside.com 2019 - 2024. All rights reserved.