我在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之后执行。
答案 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
})