Het is een asynchrone kwestie. U vult de waarde van de array in binnen een callback. Maar vanwege de aard van de gebeurtenislus is het onmogelijk dat een van de callbacks is aangeroepen tegen de tijd dat de console.log
wordt uitgevoerd.
U noemde een oplossing met beloften, en dat is waarschijnlijk de juiste weg. Bijvoorbeeld zoiets als het volgende:
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...
});
};
Let op de wijziging van forEach
naar map
...op die manier krijg je een array van alle beloften (ik neem aan dat je findOne
retourneert een belofte vanwege de .then
).
Dan gebruik je een Promise.all
wachten tot alle beloften zijn opgelost, en dan zou je je array moeten hebben.
Kanttekening:een elegantere oplossing zou zijn om newId
. terug te sturen binnen uw .then
. In dat geval Promise.all
zal daadwerkelijk oplossen met een array van de resultaten van alle beloften, wat de waarden van newId
zouden zijn .