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
.