Click here to Skip to main content
14,972,741 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
If each forEach loop is taking at least 3sec to execute.....

How to log the final works which has been modified by forEach loop? (using promise)

the current console will log the old works only, How to log modified works here?

I'm new to javascript, I'm thankful for any help towards this.

What I have tried:

const works = [
  { name: "CCS", workStatus: { isComplete: true } },
  { name: "CCB", workStatus: { isComplete: false } },
  { name: "CCF", workStatus: { isComplete: false } },
];
works.forEach(function (item) {
  setTimeout(function(){
    if (item.name === "CCF") {
      item.workStatus.isComplete = true;
    }
  }, 3000);
});
console.log("works",works);
Posted
Updated 15-Mar-21 23:21pm

1 solution

Your code runs asynchronously. The forEach method returns before any of the setTimeout callbacks have executed, so none of your array items have been modified.

You already know that you need to use a Promise to wait for the callbacks to complete:
Using Promises - JavaScript | MDN[^]

You need to turn the setTimeout call into a Promise:
javascript - How to make a promise from setTimeout - Stack Overflow[^]
JavaScript
const later = (delay) => new Promise(resolve => setTimeout(resolve, delay));

You'll need to build up a list of promises, then wait for them all to complete:
Promise.all() - JavaScript | MDN[^]
Array.prototype.map() - JavaScript | MDN[^]

It's probably easiest to use async and await:
async function - JavaScript | MDN[^]

Unfortunately, you can't use await in a top-level script, so you'll need to have an outer function to use it:
JavaScript
(async function(){
    const promises = works.map(async (item) => {
        await later(3000);
        if (item.name === "CCF") {
            item.workStatus.isComplete = true;
        }
    });
    
    await Promise.all(promises);
    console.log(works);
})();
Demo[^]

If you want to stick to using callbacks:
JavaScript
const promises = works.map((item) => later(3000).then(() => {
    if (item.name === "CCF") {
        item.workStatus.isComplete = true;
    }
}));

Promise.all(promises).then(() => console.log(works));
Demo[^]
   
Comments
gloan 16-Mar-21 5:54am
   
@RichardDeeming -Well Explained, it's a great help, thanks a lot:)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900