Amit Hagin
Amit Hagin

Reputation: 3226

eval and setTimeout in a loop

I'm holding code lines in an array, and trying to run them cell by cell with setTimeout().

This executes the code well:

for (i=0; i<restorePoints.length; i++){
    eval(restorePoints[i]);
}

but I want to have a short delay between every iteration: i want to use setTimeout() instead of eval(). for some reason none of those work:

for (i=0; i<restorePoints.length; i++){
    setTimeout(restorePoints[i],1000);
}

or

for (i=0; i<restorePoints.length; i++){
    setTimeout(eval(restorePoints[i]),1000);
}

how do I do it? thanks

Upvotes: 0

Views: 2306

Answers (2)

Felix Kling
Felix Kling

Reputation: 816810

The loop is fast. It will create all timeouts in a row, so all timeouts will fire at the same time. You can either make the time depended on the loop variable, i.e. increasing the time in every iteration, or, what I would do, use only one timeout and a recursive call:

(function() {
    var data = restorePoints;
    var run = function(i) {
        setTimeout(function() {
            var entry = data[i];
            if(entry) {
                eval(entry);
                run(i+1);
            }
        }, 1000);
    };
    run(0);
}());

Note that there is a difference between eval(string) and setTimeout(string, ...) apart from the delay:

eval will evaluate the parameter in the current scope while setTimeout (and setInterval) will evaluate it in the global scope.

This might be relevant to you.

Upvotes: 2

Jamie Dixon
Jamie Dixon

Reputation: 54011

If you're going to do it either of those ways, you'll need to wrap the function call in an anonymous function:

for (i=0; i<restorePoints.length; i++){
    setTimeout(function(){eval(restorePoints[i]}),1000);
}

Otherwise you're not setting the eval to fire in a timeout, you're setting the result of the executing Javascript code (whatever that might be in this case) to be the thing setTimeout is opperating against.

Upvotes: 2

Related Questions