Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setTimeout in forEach loop

I want to delay making a call to another function in my forEach loop if a certain condition is met, but am not understanding setTimeout in this scenario.

function checkName(person) {
    console.log('checking name of ' + person.name)
    if (person.name === 'Julie') return true 
}

function checkPersons() {
    var persons = [
        {name: 'Bob', age: 21},
        {name: 'Frank', age: 15},
        {name: 'Julie', age: 12}
    ]

    var results = []

    persons.forEach(function(person) {
        if (person.age >= 18) {
            console.log('do not need to check name of ' + person.name)
            results.push(person)
        } else {
            setTimeout(function() {
                if (checkName(person)) {
                    console.log('Julie is ' + person.name)
                    results.push(person)
                }
            }, 5000)
        }        
    }) 
}

checkPersons()

https://jsfiddle.net/nicholasduffy/sy7qpqu1/1/

I get

do not need to check name of Bob
// 5 second delay here
checking name of Frank
checking name of Julie
Julie is Julie

I would like a 5 second delay each time I need to call checkName

do not need to check name of Bob
// 5 second delay here
checking name of Frank
// 5 second delay here
checking name of Julie
Julie is Julie
like image 270
duffn Avatar asked Sep 23 '26 00:09

duffn


1 Answers

As others have mentioned, setTimeout is async, so js fires on the forEach all timeouts funcions, with a wait time of 5 seconds. So after 5 seconds, all run at the "same" time.

To avoid this, you could either do a queue and run just one timeout and when you finish call the next one, or in this case a simpler solution would be to just adjust the wait time according to the index of the person you are iterating:

persons.forEach(function(person, index) { // we add index param here, starts with 0
    //your code
    else{
        setTimeout(function() {
            if (checkName(person)) {
                console.log('Julie is ' + person.name)
                results.push(person)
            }
        }, 5000*(index+1)) // or just index, depends on your needs
    }        
}) 

This way, first one will run after 5 seconds, second one after 10, third one 15 and so on

like image 157
juvian Avatar answered Sep 24 '26 14:09

juvian



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!