Home > OS >  Ensure a Callback is Complete in Mongo Node Driver
Ensure a Callback is Complete in Mongo Node Driver

Time:01-06

I am a bit new to JavaScript web dev, and so am still getting my head around the flow of asynchronous functions, which can be a bit unexpected to the uninitiated. In my particular use case, I want execute a routine on the list of available databases before moving into the main code. Specifically, in order to ensure that a test environment is always properly initialized, I am dropping a database if it already exists, and then building it from configuration files.

The basic flow I have looks like this:

let dbAdmin = client.db("admin").admin();
dbAdmin.listDatabases(function(err, dbs){/*Loop through DBs and drop relevant one if present.*/});
return await buildRelevantDB();

By peppering some console.log() items throughout, I have determined that the listDatabases() call basically puts the callback into a queue of sorts. I actually enter buildRelevantDB() before entering the callback passed to listDatabases. In this particular example, it seems to work anyway, I think because the call that reads the configuration file is also asynchronous and so puts items into the same queue but later, but I find this to be brittle and sloppy. There must be some way to ensure that the listDatabases portion resolves before moving forward.

The closest solution I found is here, but I still don't know how to get the callback I pass to listDatabases to be like a then as in that solution.

CodePudding user response:

Mixing callbacks and promises is a bit more advanced technique, so if you are new to javascript try to avoid it. In fact, try to avoid it even if you already learned everything and became a js ninja.

Dcumentation for listDatabases says it is async, so you can just await it without messing up with callbacks:

const dbs = await dbAdmin.listDatabases();
/*Loop through DBs and drop relevant one if present.*/

The next thing, there is no need to await before return. If you can await within a function, it is async and returns a promise anyway, so just return the promise from buildRelevantDB:

return buildRelevantDB();

Finally, you can drop database directly. No need to iterate over all databases to pick one you want to drop:

await client.db(<db name to drop>).dropDatabase();
  •  Tags:  
  • Related