C'est un problème asynchrone. Vous remplissez la valeur du tableau à l'intérieur d'un rappel. Mais en raison de la nature de la boucle d'événements, il est impossible que l'un des rappels ait été appelé au moment où le console.log
est exécuté.
Vous avez parlé d'une solution impliquant des promesses, et c'est probablement la bonne approche. Par exemple, quelque chose comme ce qui suit :
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...
});
};
Notez le changement de forEach
pour map
... de cette façon, vous obtenez un tableau de toutes les promesses (je suppose que votre findOne
renvoie une promesse à cause du .then
).
Ensuite, vous utilisez un Promise.all
attendre que toutes les promesses se résolvent, puis vous devriez avoir votre tableau.
Remarque :une solution plus élégante consisterait à renvoyer newId
dans votre .then
. Dans ce cas Promise.all
se résoudra en fait avec un tableau des résultats de toutes les promesses, qui seraient les valeurs de newId
.