Search code examples
node.jsasynchronousmongojs

await doesn't wait for function to end


I know this has been asked a lot but I can't seem to use the existing answers to get my code to work. I am trying to use mongojs to make a single query, then put the results in a global (relative to the scope) variable to avoid nesting multiple callbacks. However, I can't seem to get the code to wait for the query to end before continuing.

async function taskmaster() {

    const db = mongojs(mongoUri.tasker);
    let currentDoc;
    
    const getTask = async function() { 
        db.tasks.findOne({'task_id': {'$in': [taskId, null]}}, function(err, doc) {
            console.log(doc);
            currentDoc = doc;
        });
    }

    await getTask();
    console.log(currentDoc);

    // Code to process currentDoc below
}

No matter what I do, console.log(doc) shows a valid MongoDB document, yet console.log(currentDoc) shows "undefined". Thanks in advance!


Solution

  • Inside your async function, you use findOne method() in callback style, so it's totally normal that console.log(currentDoc) shows undefined, because it executes before currentDoc = doc;

    You can promisify the findOne method, to use it with async/await keyword.

    I found a tutorial to promisfy a callback style function here, hope it help : https://flaviocopes.com/node-promisify/

    --- EDIT ---

    I rewrite your code when promising the findOne method, as suggested by O.Jones

    async function taskmaster() {
    
        const getTask = async (taskId) => {
            return new Promise((resolve, reject) => {
               db.tasks.findOne({'task_id': {'$in': [taskId, null]}}, function(err, doc) {
                  if(err) {
                      console.log("problem when retrieve data");
                      reject(err);
                  } else {
                      resolve(doc);
                  }
            });
        })
        
        const db = mongojs(mongoUri.tasker);
         
        const currentDoc = await getTask(taskId);
        console.log(currentDoc);
    }