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>