承诺带有数组的对象数组的映射

时间:2018-05-16 15:41:30

标签: javascript promise

我有以下数据结构:

[
  {
    "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

2 个答案:

答案 0 :(得分:1)

Promise.all

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个承诺的数组。