【发布时间】:2020-10-02 10:37:47
【问题描述】:
这是一个更理论的问题。我原本打算将这个问题称为是否可以对 map 进行两次迭代,但仅从它的声音来看,这听起来像是一种反模式。所以我想我只是在接近这个错误。
另请注意:这里的数据作为抽象服务器。我知道我在这里使用此处提供的数据所做的事情是不必要的,但是请不要过分关注数据结构等等。它不代表我正在使用的真实数据(更复杂,而且由客户提供,我无法更改)。而是将问题作为如何为每个数组项返回结构化异步调用来解决! :-)
我的问题归结为:
- 我有
ids 数组,我需要在其上执行两个单独的异步调用 - 这两个调用都需要通过(并且在所有
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 与@987654330 的预定数组不是异步的@s.
我正在考虑类似于 map 的 Promise 列表以供 Promise.all 执行。当您只需要映射一个 api 调用时,这很好用:
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 Promises 数组中。
我想我总是可以简单地为两个 API 调用实例做两个映射的
flatMap,但这听起来有点愚蠢,因为
- 我会在同一个数组上执行 array.map 两次
- 我的数据结构没有逻辑连接(同一用户的两个单独的数组项,甚至不会互相跟随)
所以理想情况下我想以
的形式返回 dat const result = await Promise.all([...])
console.log(result)
/* [
* {id: 'a', message: 'hello', name: 'Samuel'},
* {id: 'b', message: 'world', name: 'John'},
* ]
或者我是否只需要对 Promise 进行平面映射,然后在已解析的 Promise.all 上的单独处理程序中根据 id 标识符对对象进行数据合并?
我在此处提供了单 api-call 模型的工作示例,因此您不必复制粘贴。
解决此类问题的正确/常用方法是什么?
【问题讨论】:
-
您为什么需要致电
fetchFor(dataMessages, id)?您是否只需将id的消息添加到user(如果有的话)? -
@Andreas 不。我知道在示例中它是有道理的,但不要将消息 / id 视为实际数据库中的数据字段(显然实际上我返回的不仅仅是一个字段)。我只是选择了这两件事作为问题的抽象,作为我必须做的(更复杂的)事情的表示。问题是关于在单个地图中返回两个结构化 Promise,所以不要过分关注数据结构的正确性以及其他问题:-)
标签: javascript typescript asynchronous async-await es6-promise