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

How to approach multiple async calls on single array?

这是一个更具理论性的问题。我原本打算将这个问题称为是否可以对 map 进行两次迭代,但仅从它的声音来看,这听起来像是一种反模式。所以我假设我只是在接近这个错误。

Also note: Data here servers as an abstraction. I know that what I'm doing here with data provided here is unnecessary, but please don't get fixated too much on data-structure and what-not. It does not represent the real (more complex, which furthermore is provided by client and I can't alter) data I'm working with. Instead approach the problem as how to return structured async calls for each array item please! :-)


我的问题归结为:

举个例子,假设我有这两个数据集:

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 与预定的 id 数组不异步。

我在想类似于 mapPromise.all 执行的 Promise 列表。当您只需要映射一个 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}]
}

然而我不知何故需要 return 两个承诺

Promise.all Promise 数组中。


I guess I could always simply do a flatMap of two maps for both instances of API calls, but that sounds kinda dumb, given

  • I'd be doing array.map on same array twice
  • My data structure would not be logically connected (two separate array items for the same user, which would not even by followed by eachother)

所以理想情况下,我想 return dat 的形式

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

或者我是否只需要对承诺进行平面映射,然后在已解析的 Promise.all 上的单独处理程序中基于 id 标识符对对象进行数据合并?

我在此处提供了单个 api 调用模型的工作示例,因此您无需复制粘贴。

解决此类问题的正确/常用方法是什么?

您可以嵌套 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)
  )
]);

如果您希望在检索后合并结果,这只是标准数据操作的问题。