Je to asynchronní problém. Vyplňujete hodnotu pole uvnitř zpětného volání. Ale kvůli povaze smyčky událostí je nemožné, aby bylo v době console.log zavoláno některé ze zpětných volání se provede.
Zmínil jste řešení zahrnující sliby, a to je pravděpodobně správný postup. Například něco jako následující:
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...
});
};
Všimněte si změny forEach map ...tak získáte řadu všech slibů (předpokládám, že váš findOne vrací slib kvůli .then ).
Pak použijete Promise.all počkat, až se vyřeší všechny sliby, a pak byste měli mít své pole.
Poznámka:Elegantnější řešení by zahrnovalo vrácení newId uvnitř vašeho .then . V tom případě Promise.all se ve skutečnosti vyřeší polem výsledků všech slibů, což by byly hodnoty newId .