使用 promises 索引映射 Promise.all 输出
Posted
技术标签:
【中文标题】使用 promises 索引映射 Promise.all 输出【英文标题】:Map Promise.all output with promises index 【发布时间】:2018-04-27 09:16:51 【问题描述】:我正在使用支持默认异步等待代码样式的 nodejs v8+。
在我的问题中,我试图将所有承诺推送到一个数组中,然后使用 Promise.all 和 await 关键字来获取响应。但问题是,我无法用键映射承诺。
示例如下:
let users = ["user1", "user2", "user3"];
let promises = [];
for(let i = 0; i < users.length; i++)
let response = this.myApiHelper.getUsersData(users[i]);
promises.push(response);
let allResponses = await Promise.all(promises);
在这里我得到了所有响应的所有收集响应,但我实际上想按用户映射它。 例如,目前我正在以这种格式获取数据:
[
user1 Data from promise 1
,
user2 Data from promise 2
,
user3 Data from promise 3
]
但我想要这种格式的数据:
[
"user1": Data from promise 1
,
"user2": Data from promise 2
,
"user3": Data from promise 3
]
我确信必须有一种方法来映射用户的每一个承诺,但我不知道。
【问题讨论】:
【参考方案1】:我们将创建一个用户数组。迭代它以创建一个 Promise
数组,我们将其提供给 Promise.all
。然后迭代答案以创建一个将用户与来自getUsersData
的相关答案匹配的对象。
关于 Promise.all 要了解的是,返回数据的顺序取决于它的条目中给出的promises
的顺序。
const users = ['user1', 'user2', 'user3'];
const rets = await Promise.all(users.map(x => this.myApiHelper.getUsersData(x)));
const retWithUser = rets.map((x, xi) => (
user: users[xi],
ret: x,
));
Here你有一个关于数组方法的很棒的教程(map, filter, some...)
。
【讨论】:
【参考方案2】:虽然我接受的答案是解决方案之一,但我认为它是完美的,我将保留为已接受的答案,但我想发布我的解决方案,我后来发现它更简单:
我们可以简单地使用这个:
let finalData = ;
let users = ["user1", "user2", "user3"];
await Promise.all(users.map(async(eachUser) =>
finalData[user] = await this.myApiHelper.getUsersData(eachUser);
))
console.log(finalData);
【讨论】:
【参考方案3】:如此处所述 How to use Promise.all with an object as input
这是一个简单的 ES2015 函数,它接受一个具有可能是 Promise 的属性的对象,并返回该对象的 Promise 以及已解析的属性。
function promisedProperties(object)
let promisedProperties = [];
const objectKeys = Object.keys(object);
objectKeys.forEach((key) => promisedProperties.push(object[key]));
return Promise.all(promisedProperties)
.then((resolvedValues) =>
return resolvedValues.reduce((resolvedObject, property, index) =>
resolvedObject[objectKeys[index]] = property;
return resolvedObject;
, object);
);
然后你会像这样使用它:
var promisesObject = ;
users.map((element, index) => object[element] = this.myApiHelper.getUsersData(users[index]));
promisedProperties(object).then(response => console.log(response));
请注意,首先您需要一个带有 key/promise 的对象。
【讨论】:
虽然我没有投反对票,这似乎是一个可行的解决方案,但同时它有点复杂。所以接受了一个简单的解决方案以上是关于使用 promises 索引映射 Promise.all 输出的主要内容,如果未能解决你的问题,请参考以下文章
在 Javascript 数组映射中使用 promise 函数
React 帮助:在映射数组中使用 Promise 进行条件渲染 [关闭]