0

I'm requesting a JSON API then doing a for each loop over a JSON object and want a way to know once it's complete. This is my current for each loop

Object.entries(jsonbody.data.users).forEach(([key, value]) => {
 //code to run for each user 
});

At the moment it'll just loop through each user till it's completed them all but I have no definitive max number of objects there could be so I can just do the usual loop counting technique.
I'm not sure if I've just got this completely wrong but I've always had trouble working out how to perform synchronous events with node js so hopefully, this will teach me

Charlie Simon
  • 133
  • 12

1 Answers1

1

It depends on whether the "code to run for each user" is synchronous or asynchronous.

There isn't enough detail in your question to give a definitive answer.

If the code in the loop is synchronous then the loop will complete before any code after it will run.

That is the definition of synchronous code ;)

let count = 0;
Object.entries(jsonbody.data.users).forEach(([key, value]) => {
  // some sync code to run for each user 
  count++;
});

// Because the code in your loop is synchronous then we'll only get to this
// part of the code once the code above is complete.
console.log(`The tasks have finished`);
console.log(`count of users=`, count);

If the per-user code is asynchronous then you will need to wait until all tasks have completed before continuing.

It is common to use Promises for this:

// Note the use of `.map()` here instead of `.forEach()` that is used in previous example
const promises = Object.entries(jsonbody.data.users).map(([key, value]) => {
  return new Promise((resolve, reject) => {
    // some async code to run for each user 
    
    // Resolving to `key` here for example only - you might return data from 
    // some `fetch()` request or other async task
    resolve(key);
  });
});

// Because the code above is **asynchronous** then we'll reach this point in code 
// before the code above has "finished" (i.e. there are still outstanding tasks).

// We have to wait until those tasks have completed using either `await` or `promise.then()`
const results = await Promise.all(promises);
console.log(`The tasks have finished. results=`, results);

// OR use `promise.then(...)`
Promise.all(promises).then((results) => {
    console.log(`The tasks have finished. results=`, results);
});
Sly_cardinal
  • 12,270
  • 5
  • 49
  • 50
  • Wow, this makes so much sense! I'll give it a try and let you know but this really clears things up, I'm not sure why but I struggle to grasp asynchronous and synchronous code especially when most examples online aren't always the most practical from a first glance and so I tend just to find workarounds rather than try and understand. But this certainly helps. Thanks – Charlie Simon Feb 21 '22 at 10:26