Delayed javascript function/handler gets the right variable/parameter values

So we have a function that adds a handler function that is called after an ajax load or at a later time and we need to execute the handler function code for each item inside an array allowing the function to access the array values. Usually with the simplest try you would get some code that get’s executed with invalid variable values. Examples are below.

The wrong code:

//the function that will do the stuff for each array
var dostuff = function (arr) {
var n = arr.length,
    i;
    for(i = 0; i < n; i++) {
        var o = arr[i];
        //event bind or delayed function call
        setTimeout(function () {
                //we want to access here the correct arr[i]
                //when the code gets here the value of o is arr[arr.length-1]
                console.log(o);
        }, 1000);
    }
}
dostuff([1,2,3,4]);

You can load the code into your javascript console to see it in action.
The output appears after 1 second and it is like this:

4
4
4
4

I don't need that. I need something that works so we need to wrap the handler call into a function call that will pass the current values as parameters.

var dostuff = function (arr) {
var n = arr.length,
    i;
    for(i = 0; i < n; i++) {
        var o = arr[i];
        (function (y) {
            setTimeout(function () {
                console.log(y);
            }, 1000);
        }) (o);
    }
}
dostuff([1,2,3,4]);

The output appears after 1 second and it is like this:

1
2
3
4

The final best solution would be to have the function inside for already defined so you don't define it on every loop:

var dostuff_item = function (y) {
            setTimeout(function () {
                console.log(y);
         }, 1000);
 }
var dostuff = function (arr) {
var n = arr.length,
    i;
    for(i = 0; i < n; i++) {
        var o = arr[i];
        dostuff_item (o);
    }
}
dostuff([1,2,3,4]);

Tada!

Leave a Reply

Your email address will not be published. Required fields are marked *