如何处理单个数组上的多个异步调用?
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! :-)
我的问题归结为:
- 我有
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
与预定的 id
数组不异步。
我在想类似于 map
为 Promise.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 两个承诺
fetchFor(dataMessages, id)
fetchFor(dataNames, id)
在 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)
)
]);
如果您希望在检索后合并结果,这只是标准数据操作的问题。
这是一个更具理论性的问题。我原本打算将这个问题称为是否可以对 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! :-)
我的问题归结为:
- 我有
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
与预定的 id
数组不异步。
我在想类似于 map
为 Promise.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 两个承诺
fetchFor(dataMessages, id)
fetchFor(dataNames, id)
在 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)
)
]);
如果您希望在检索后合并结果,这只是标准数据操作的问题。