Q:

How to properly chain promises inside of a forEach loop in Javascript

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.

A:

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
});

