Reputation: 1253
I'm using mongo and need to do an async call for each item inside of a loop. I'd like to execute another command once all of the promises inside of the loop have completed, but so far the promises in the loop seem to be completing after the code that's in the then that's after the loop.
Essentially i'd like the order to be
Loop promises then other code
instead of what it is now which is
other code Loop promises
MongoClient.connect(connecturl)
.then((client) => {
databases.forEach((val) => {
val.collection.forEach((valcol) => {
client.db(val.databasename).stats() //(This is the async call)
.then((stats) => {
//Do stuff here with the stats of each collection
})
})
})
})
.then(() => {
//Do this stuff after everything is finished above this line
})
.catch((error) => {
}
Any assistance would be appreciated on this one.
Upvotes: 2
Views: 2172
Reputation: 707178
Assuming the things you are using .forEach()
on are iterables (arrays or something like that), you can use async/await
to serialize a for/of
loop:
MongoClient.connect(connecturl).then(async (client) => {
for (let db of databases) {
for (let valcol of db.collection) {
let stats = await client.db(db.databasename).stats();
// Do stuff here with the stats of each collection
}
}
}).then(() => {
// Do this stuff after everything is finished above this line
}).catch((error) => {
// process error
})
If you wanted to stick with your .forEach()
loops, you could make it all work if you did things in parallel and used Promise.all()
to know when it's all done:
MongoClient.connect(connecturl).then((client) => {
let promises = [];
databases.forEach((val) => {
val.collection.forEach((valcol) => {
let p = client.db(val.databasename).stats().then((stats) => {
// Do stuff here with the stats of each collection
});
promises.push(p);
});
});
return Promise.all(promises);
}).then(() => {
// Do this stuff after everything is finished above this line
}).catch((error) => {
// process error here
});
Upvotes: 4