Why my async function doesn't await to the Promise in JavaScript?

My code is the following:

const match = async (tender, searchCriteria) => {

  const tenderAccount = await tenderAccountController.findOrCreate(
    tender,
    searchCriteria,
  );

  if (searchCriteria.emailFrequency !== 'real-time') {
    return null;
  }

  // Notify Stakeholders
  await notifyStakeholders(tender, tenderAccount, searchCriteria);
};

This function "match" is called inside a for loop [for (const searchCriteria of searchCriterias) {}]

findOrCreate function is the following:

exports.findOrCreate = async (tender, searchCriteria) => {
    console.log("Search Criteria Name: " + searchCriteria.name)
    console.log("Tender Name: " + tender.name)

    // Check if it already exists
    let doc = await TenderAccount.findOne({
        tender: tender._id,
        account: searchCriteria.account._id
    })

    console.log("Doc: " + doc)
  
    if(doc) {
        // If it exists, update searchCriterias
        await TenderAccount.updateOne({ _id: doc._id }, { $addToSet: { searchCriterias: searchCriteria } })

        return doc;
    } else {
        doc = await TenderAccount.create({
            tender,
            account: searchCriteria.account,
            searchCriterias: [searchCriteria],
            dueDate: tender.submissionDeadlineDate
        })

        return doc;
    }
};

My problem is that it doesn’t await to findOne query. It just complete all the inital loop (searchcriteria loop) and when loop ended it returns the query result.
In my console I got this:

Search Criteria Name: test-sc
Tender Name: test-tender
Search Criteria Name: test2-sc
Tender Name: test2-tender
Search Criteria Name: test3-sc
Tender Name: test3-tender
Doc: null
Doc: null
Doc: null

And I don’t understand it, it supose to console.log the doc after the tender name console.log right?

I will appreciate your answers.

>Solution :

When you call an async function without calling await, it will continue execution without waiting for the promise to be resolved. So if your for loop looks like: for (...) match(...) instead of for (...) await match(...), it will execute all matches immedietly one after the other hence why the Search Criteria Name and Tender Name all get printed first in a row.

Adding await to the match call should give the result you were expecting.

Leave a Reply