Home > Net >  Timeout within array executes does not execute first
Timeout within array executes does not execute first

Time:10-15

I am trying to print text with timeout within map function, and then say that it's done, but 'done' is printed before the array and I can't figure out how to fix it:

const arrayImages = [
    [
        {
            url: 'img/man.jpg',
        }, 
        {
            url: 'img/bike.jpg',
        }, 
        {
            url: 'img/sun.jpg'
        },
    ]
]

function clickMe(){  
arrayImages[0].map((element, index) => {
  setTimeout(() => {
     alert(index);
     if (index === 5)
       return;
  },2000 * index);  
 });

  alert("Done");
}
<button onclick="clickMe()" type="button">Click Me!</button>

CodePudding user response:

Your alert is executed synchronously -- long before any of the asynchronous callback calls are made. The place to show that "done" is when the last setTimeout callback is executed, so when index is arrayImages[0].length-1.

But this is not a very elegant way to do it. Moreover, map returns an array, so that is not really the appropriate looping method to use.

Instead, look at promises.

First promisify setTimeout and then loop with a plain for loop within an async function:

// Promisify setTimeout
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

const arrayImages = [[{ url: 'img/man.jpg',},{ url: 'img/bike.jpg',},{ url: 'img/sun.jpg'},]]

async function clickMe() {
    for (const element of arrayImages[0]) {
        await delay(1000);
        console.log(element.url);
    }
    console.log("done");
}
<button onclick="clickMe()" type="button">Click Me!</button>

  • Related