节点js - 在所有承诺解决后发送响应

时间:2016-07-29 08:14:41

标签: javascript json node.js express

我在NodeJS Express中定义了一条路线。

路由多次调用一个函数(返回一个promise)。从这些Promises返回的值被添加到一个Array中,然后使用res.json()将其发送回客户端。

我面临的问题是,当Promise得到解决时,res.json()会执行,因为它不会等待Promises返回。我认为需要某种链接机制,但不能知道如何做到这一点。

以下是我的代码

app.get('/markers', function(req, res) {
       var markers = [];
    var marker1 = {"id": 1, "name": "London"};
 // Get the lat and lng based on the address
    geocoding(marker1.name).then(function(geocode) {
        marker1.lat = geocode[0].latitude;
        marker1.lng = geocode[0].longitude;
        markers.push(marker1);
    }, function(error) {
        console.log(error);
    })

    var marker2 = {"id": 2, "name": "Chicago" };
    geocoding(marker2.name).then(function(geocode) {
        marker2.lat = geocode[0].latitude;
        marker2.lng = geocode[0].longitude;
        markers.push(marker2);
    }, function(error) {
        console.log(error);
    })
     var marker3 = {"id": 3, "name": "Munich" };
     geocoding(marker3.name).then(function(geocode) {
        marker3.lat = geocode[0].latitude;
        marker3.lng = geocode[0].longitude;
        markers.push(marker3);
    }, function(error) {
        console.log(error);
    })
  // return the lat and lng array to the client
    res.json(markers);

})

我如何确保' res.json(标记);'在解决了所有三个Promise之后执行。

2 个答案:

答案 0 :(得分:6)

您只需使用Promise.all,这将在所有承诺得到解决时解决:

app.get('/markers', function(req, res) {
    var markers = [];
    var marker1 = {"id": 1, "name": "London"};

 // Get the lat and lng based on the address
    var prom1 = geocoding(marker1.name).then(function(geocode) {
        marker1.lat = geocode[0].latitude;
        marker1.lng = geocode[0].longitude;
        markers.push(marker1);
    }, function(error) {
        console.log(error);
    })

    var marker2 = {"id": 2, "name": "Chicago" };
    var prom2 = geocoding(marker2.name).then(function(geocode) {
        marker2.lat = geocode[0].latitude;
        marker2.lng = geocode[0].longitude;
        markers.push(marker2);
    }, function(error) {
        console.log(error);
    });

    var marker3 = {"id": 3, "name": "Munich" };
    var prom3 = geocoding(marker3.name).then(function(geocode) {
        marker3.lat = geocode[0].latitude;
        marker3.lng = geocode[0].longitude;
        markers.push(marker3);
    }, function(error) {
        console.log(error);
    });
  // return the lat and lng array to the client

    Promise.all([prom1, prom2, prom3]).then(function() {res.json(markers);}).catch(function(err) {console.error(err);});
})

答案 1 :(得分:1)

您可以使用Promise.all函数等待多个承诺结果。

您还可以使用Array.prototype.map准备一系列promises以减少代码重复。

你应该妥善处理承诺拒绝。

app.get('/markers', function(req, res, next) {
  var markers = [{
    id: 1,
    name: 'London'
  }, {
    id: 2,
    name: 'Chicago'
  }, {
    id: 3,
    name: 'Munich'
  }];
  // you could use .map to generate an array of promises
  var promises = markers.map(function (marker) {
    return geocoding(marker.name);
  })
  // and then use Promise.all to await their results
  Promise.all(promises).then(function (geocodes) {
    // you could use .map again to generate resulting json
      res.json(geocodes.map(function (geocode) {
      return {
        lat: geocode[0].latitude,
        lng: geocode[0].longitude
      }
    }));
  }).catch(next) // handle promise rejection
})