我有以下数据结构:
[
{
"id": 1,
"houses": [
{
"id": 1,
"name": "house 1"
},
{
"id": 2,
"name": "house 2"
}
]
},
{
"id": 2,
"houses": [
{
"id": 3,
"name": "house 3"
}
]
}
]
我希望能够为每个用户中的每个房子做一些异步,所以我有一个带有这个签名的函数并返回一个承诺:
sendWelcomeEmail(user, house)
现在,我知道当我有一组promises时如何使用Bluebird' Promise.map
,但在这种情况下,我有一个带数组的对象数组。调用Promise.map
的正确方法是什么,以便最终为每个用户和住宅调用sendWelcomeEmail
?
答案 0 :(得分:1)
Promise.all(iterable)方法返回一个Promise,它在iterable参数中的所有promise都已解析或者iterable参数不包含promise时解析。它拒绝承认拒绝的第一个承诺。
const data = [{
"id": 1,
"houses": [{
"id": 1,
"name": "house 1"
},
{
"id": 2,
"name": "house 2"
}
]
},
{
"id": 2,
"houses": [{
"id": 3,
"name": "house 3"
}]
}
];
const fakeSendWelcomeEmail = (id, house) => Promise.resolve(`${id} / ${house.name}`);
// Transforming the data into a flat array that contains the return value of fakeSendWelcomeEmail .
// So welcomeResults is an array of Promise.
const welcomeResults = data.reduce((res, user) => {
return res.concat(user.houses.map((house) => {
return fakeSendWelcomeEmail(user.id, house)
}));
}, [])
Promise.all(welcomeResults)
.then((results) => {
console.log(results);
})

我自己写了一个Promise polyfill,如果你对这些东西的工作原理感到好奇,或者只是对Promise有所了解。
答案 1 :(得分:0)
您需要将reduce与地图结合起来。
const promises = mainArray.reduce((acc, cur) => {
return acc.concat(cur.houses.map(house => sendWelcomeEmail(house)));
}, []);
根据你的例子,promises将是一个包含3个承诺的数组。