Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add additional parameters to callback function

I'm building a system in Node.js that is supposed to find all files in an array of folders, stat them, and then do some additional work using that information.

I'm using fs.readdir() to get all the files synchronously from each of the folders. My code looks like this:

for(i=0,max=paths.length; i<max; i++) {
    var path = paths.pop();
    console.log("READING PATH: " + path);
    fs.readdir(path, function(err, files) { handleDir(err, files, path); });
}

The problem is that, depending on how fast the readdir() executes, handleDir() is getting the wrong path. This happens because by the time the callback runs, the next loop has already started - meaning that the path variable has changed.

So, what I need to do is somehow lock that path variable to it's specific callback function. I can't think of any good way to do this - anyone have some ideas?

like image 313
jwegner Avatar asked May 13 '11 20:05

jwegner


2 Answers

There is no block scope, so use a function for scope.

for(var i=0, path, max=paths.length; i<max; i++) {
    path = paths.pop();
    console.log("READING PATH: " + path);
    handlePath( path );
}
function handlePath ( path ) {
    fs.readdir(path, onPathRead);
    function onPathRead (err, files) {
        handleDir(err, files, path);
    }
}
like image 82
generalhenry Avatar answered Sep 25 '22 00:09

generalhenry


This is one of the more annoying parts of JS for me. An alternative to creating a separate function (as @generalhenry demonstrated) is to wrap the code in an anonymous function that's executed before the path variable changes.

for(i=0,max=paths.length; i<max; i++) {
    var path = paths.pop();
    console.log("READING PATH: " + path);
    fs.readdir(path,
        (function(p){
            return function(err, files) {
                handleDir(err, files, p);
            };
        })(path);
    );
}

Either way, the important point is that the function's context (anonymous or not) is initiated before the value of the path variable is reassigned.

like image 35
Richard Marr Avatar answered Sep 24 '22 00:09

Richard Marr