2016-07-29 6 views
3

Ich habe eine Route in NodeJS Express definiert.Knoten js - Antwort senden, nachdem alle Zusagen aufgelöst wurden

Die Route ruft eine Funktion mehrere Male auf (wodurch eine Zusage zurückgegeben wird). Der von diesen Promises zurückgegebene Wert wird einem Array hinzugefügt, das dann mithilfe von res.json() an den Client gesendet wird.

Das Problem, mit dem ich konfrontiert bin, ist, dass, während Promises aufgelöst werden, res.json() ausgeführt wird, da es nicht auf die Rückkehr der Versprechen wartet. Ich denke, es wird eine Art Verkettungsmechanismus benötigt, aber ich kann nicht herausfinden, wie es geht.

Unten ist mein Code

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); 

}) 

Wie kann ich sicherstellen, dass 'res.json (Marker);' wird ausgeführt, nachdem alle drei Versprechen gelöst wurden.

Antwort

5

Sie verwenden nur Promise.all, die aufgelöst wird, wenn alle Versprechen gelöst werden:

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);}); 
}) 
0

Sie für mehrere Versprechen Ergebnisse Promise.all Funktion erwarten könnte.

Sie könnten auch Array.prototype.map verwenden, um eine Reihe von Versprechungen zu erstellen, die Code-Duplizierung zu reduzieren.

Und Sie sollten mit Ablehnungen richtig umgehen.

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 
}) 
Verwandte Themen