Search code examples
node.jspromisemongodb-.net-driver

Node.js MongoDb find function ignores wait


I need the callback function of find from Node.js mongodb 3.1.6 to be triggered before the return statement of an async function, however the return statement is called before the callback function even-though there is a wait in front.

async function(myId) {
  const myObject = MyObject()
  await collection.find({where: {id: myId}}, async (err, results) => {
        if (err) {
          logger.error('error');
        }
        myObject.add(results);
      });
  return myObject
}

I have seen some examples where instead of find(query, callback) the pattern find(query).toArray() was used. But this doesn't run at all in my case. We use Node.js mongodb 3.1.6 with loopback-connector-mongodb maybe this is related to the problem.


Solution

  • If mongo doesn't provide a promise-answering function, then promisify this one yourself. Neither that promise-creating wrapper nor the anonymous callback it uses should be declared async, but the caller should....

    function findById(collection, myId) {
      return new Promise((resolve, reject) => {
        collection.find({where: {id: myId}}, (err, results) => {
          (err)? reject(err): resolve(results);
        });
      });
    }
    
    // now callers can use the async await pattern...
    async someFunction() {
      try {
        let myId = // ...
        let collection = // ...
        let results = await findById(collection, myId);
        // do something with results
      } catch (err) {
        // error
      }
    }
    

    The key idea is that collection.find with the callback isn't eligible for await, because it doesn't return a promise. The anonymous callback function you pass to it isn't an async function... it does its work right away, as soon as find calls it back. So we build a promise around mongo, then use the new async/await syntax with that promise.