Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

226
Views
Unable to understand asynchronous functions in NodeJS

I have spent 6 hours already trying to figure out how to do this in NodeJS.

I am using NodeJS with Express and MongoDB.

I have a database that has two collections viz. Listings and Categories. Each listing has a "category" which is an ID that maps to a category inside the Categories collection.

What I want to do is, fetch all the listings, then loop through all of them, and get the category title from the Categories collection using the category id.

This is what I had for getting all the listings:

const listings_raw = [];

await db.collection("listings").find().forEach(listing => listings_raw.push(listing));

The code above works fine. The trouble I am having is with this:

const listings = [];

listings_raw.forEach(async listing => {
    const category_id = listing.category;

    const category_title = await db.collection('categories').findOne({_id: objectId(category_id)});

    listing.category_title = category_title;

    listings.push(listing);
});

response.send(listings);

The response.send(listings); gets executed before the listings_raw.forEach completes.

I want to send the data only after all listings have been populated with the category titles.

After spending 6 hours, I have come up with the following hack which I am sure is nasty!

const listings_raw = [];

const em = new events.EventEmitter();

await db.collection("listings").find().forEach(listing => listings_raw.push(listing));

const listings = [];

let counter = 0;

listings_raw.forEach(async (listing) => {
    const category_id = listing.category;

    const category = await db.collection('categories').findOne({_id: objectId(category_id)});

    listing.category_title = category.title;

    listings.push(listing);

    if (counter === listings_raw.length - 1) {
        em.emit('listings:processing:done');
    }

    counter++;
});

em.on('listings:processing:done', () => {
    response.send(listings);
});

Please, can someone explain or guide me on how this should be done in JavaScript?

Basically, I am not able to figure out how to know if all promises have been resolved or not.

Thank you!

almost 4 years ago · Santiago Trujillo
1 answers
Answer question

0

The listings_raw.forEach function executes synchronously on the array, even though you are then performing an asynchronous operation within that.

Promise.all will allow you to await for the result of an array of promises. Therefore you can .map the listings to an array of promises which return the updated listing.

const listings = await Promise.all(listings_raw.map(async listing => {
    const category_id = listing.category;

    const category_title = await db.collection('categories').findOne({_id: dependencies.objectId(category_id)});

    listing.category_title = category_title;

    return listing;
});

response.send(listings);
almost 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!