Es ist ein asynchrones Problem. Sie füllen den Wert des Arrays in einem Callback aus. Aufgrund der Art der Ereignisschleife ist es jedoch unmöglich, dass bis zum Zeitpunkt der console.log
einer der Rückrufe aufgerufen wurde wird ausgeführt.
Sie haben eine Lösung mit Versprechungen erwähnt, und das ist wahrscheinlich der richtige Weg. Zum Beispiel etwas wie das Folgende:
exports = function(orgLoc_id, data) {
// ...
let stream_ids = [];
const promises = data.map(function(stream) {
return streamsCollection.findOne({ _id: stream.stream_id }, { type: 1, sizes: 1 })
.then(res => { //if I comment this query it will push without any problem
if (res) {
let newId = new BSON.ObjectId();
// ...
stream_ids.push(newId);
}
})
})
Promise.all(promises).then(function() {
console.log('stream ids: ' + stream_ids);
//TODO
// any code that needs access to stream_ids should be in here...
});
};
Beachten Sie die Änderung von forEach
zu map
...auf diese Weise erhalten Sie ein Array aller Promises (ich nehme an, Ihr findOne
gibt wegen .then
ein Promise zurück ).
Dann verwenden Sie ein Promise.all
zu warten, bis alle Versprechungen aufgelöst sind, und dann sollten Sie Ihr Array haben.
Randnotiz:Eine elegantere Lösung wäre die Rückgabe von newId
innerhalb Ihres .then
. In diesem Fall Promise.all
wird tatsächlich mit einem Array der Ergebnisse aller Promises aufgelöst, was die Werte von newId
wären .