For-loop and async callback in node.js?

exkoria picture exkoria · Sep 1, 2011 · Viewed 12k times · Source

I'm new to JavaScript and to node.js. I want to loop through a directory and add all file stat (not other directories) to an array. As you see below there is a problem with my code since the callback will probably get called after the for loop has finished so using the "i"-variable in the callback method will not work. But how should the code look so that the below snippet works? Does it have something to do with closures?

Thanks for help!

    fs.readdir(SYNCDIR, function(err1, files) {
        var filesOnly = [];

        if(!err1) {

            for(var i = 0; i < files.length; i++) {

                var imgFilePath = SYNCDIR + '/' + files[i];
                fs.stat(imgFilePath, function(stat){

                    if (stat.isFile()){
                        filesOnly[i] = stat; // This will not be correct since the for-loop has finished
                    }
                });

            }
        }
    });

Answer

Gary Chambers picture Gary Chambers · Sep 1, 2011

You are right about needing to use a closure. You should wrap the contents of the for loop in a self-invoking function to preserve the value of i for each iteration.

fs.readdir(SYNCDIR, function(err1, files) {
    var filesOnly = [];

    if(!err1) {

        for(var i = 0; i < files.length; i++) {

            (function(i) {
                var imgFilePath = SYNCDIR + '/' + files[i];
                fs.stat(imgFilePath, function(stat){
                    if (stat.isFile()){
                        filesOnly[i] = stat;
                    }
                });
            })(i);

        }
    }
});