È un problema asincrono. Stai compilando il valore dell'array all'interno di un callback. Ma a causa della natura del ciclo di eventi, è impossibile che qualcuno dei callback sia stato chiamato prima del console.log
viene eseguito.
Hai menzionato una soluzione che coinvolge le promesse, e questa è probabilmente la strada giusta. Ad esempio qualcosa come il seguente:
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...
});
};
Nota la modifica di forEach
alla map
...in questo modo otterrai un array di tutte le Promesse (suppongo che il tuo findOne
sta restituendo una promessa a causa di .then
).
Quindi usi un Promise.all
aspettare che tutte le promesse si risolvano, e poi dovresti avere il tuo array.
Nota a margine:una soluzione più elegante comporterebbe la restituzione di newId
dentro il tuo .then
. In tal caso Promise.all
si risolverà effettivamente con un array dei risultati di tutte le promesse, che sarebbero i valori di newId
.