在循环中链接承诺

时间:2017-07-06 23:23:12

标签: javascript promise

我面临着一个复杂的承诺链,看起来结果并没有等到承诺的结束。

return Promise.all([
  Radar.newRadar(1),
  Radar.newRadar(2),
  Radar.newRadar(3)
])
.then( newRadarIds => {
    let RadarNotes = [];
  return Promise.all([
     _.map(newRadarIds, (radar_id) =>{
      return Promise.all([
        Radar.init(radar_id)
      ])
      .then( kpis => {
        return Promise.all([
          Radar.addKpis(radar_id.radar_id, ...)
        ])
        .then( radarAddKpi => {
          RadarNotes.push({
            year : radar_id.year,
            data : kpis[0].data});
            console.log('in map')
          // return {
          //   year : radar_id.year,
          //   data : kpis[0].data}
        })
        .catch( err => {
          console.error(err);
        })
      })

    }) //end map
  ])
  .then(result => {
    console.log('her222e')
    res.json(result)
  })
  .catch (err => {
    console.error(err);
  })
  })
.catch( error => {
  console.error(error);
})

我在'in map'之前得到输出'here'。目标是填充数组并通过res.json调用将其发送给客户端。

我错过了什么?

1 个答案:

答案 0 :(得分:3)

罪魁祸首是

return Promise.all([
  _.map(newRadarIds, (radar_id) =>{
    return // a promise
  }) //end map
])

在promises的数组的数组上调用Promise.all。哪个不会等待。您将要删除数组文字,并将map的结果 - 承诺数组 - 直接传递给Promise.all

使用单元素数组(Promise.all([ … ])Radar.init)调用Radar.addKpis是非常多余的(如果您不希望结果是数组,则可能有害)。只需将then直接链接到您的承诺即可。

最后,您的result将包含undefined条目,因为您的承诺无法解决任何问题。您需要明确发送RadarNotes。但推送到该数组更好的是履行每个结果的承诺,以便Promise.all可以为所有结果的数组构建承诺:

return Promise.all([
  Radar.newRadar(1),
  Radar.newRadar(2),
  Radar.newRadar(3)
])
.then(newRadarIds =>
  Promise.all(_.map(newRadarIds, radar_id =>
    Radar.init(radar_id)
    .then(kpi =>
      Radar.addKpis(radar_id.radar_id, ...)
      .then(radarAddKpi =>
        ({
          year : radar_id.year,
          data : kpi.data
        })
      )
    )
  ))
)
.then(result => {
  res.json(result)
})
.catch (err => {
  console.error(err);
})