Ini masalah asinkron. Anda sedang mengisi nilai array di dalam panggilan balik. Tetapi karena sifat dari loop peristiwa, tidak mungkin callback mana pun akan dipanggil pada saat console.log dijalankan.
Anda menyebutkan solusi yang melibatkan janji, dan itu mungkin taktik yang tepat. Misalnya seperti berikut ini:
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...
});
};
Perhatikan perubahan forEach ke map dengan cara itu Anda mendapatkan larik dari semua Janji (saya berasumsi findOne Anda mengembalikan janji karena .then ).
Kemudian Anda menggunakan Promise.all untuk menunggu semua janji diselesaikan, dan kemudian Anda harus memiliki array Anda.
Catatan tambahan:Solusi yang lebih elegan akan melibatkan pengembalian newId di dalam .then . Anda . Dalam hal ini Promise.all akan benar-benar diselesaikan dengan larik hasil semua janji, yang akan menjadi nilai newId .