Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js: problem with variable scope in callback

var result = { controllers: [], views: [], models: [] };
var dirs = ['controllers', 'views', 'models'];

dirs.forEach(function(dirname) {
    fs.readdir('./' + dirname, function(err, res) {
        if (err) throw err;
        result[dirname] = res;
        // #2
    });
});

// #1

In this snippet of code, having console.log(result); running at #1 (see above), empty controller, views, and models arrays just as initialized will be logged. However, I need the loop to fill the arrays with corresponding file names read via fs.

console.log(result); at #2 will log the result object filled with the desired values after the third iteration.

I believe this has something to do with the asynchronous nature of Node.js / JavaScript callbacks. Please forgive me if I'm not understanding how JavaScript variable scopes and async methods work, I'm all new to this.

like image 447
Daniel Avatar asked Feb 26 '26 04:02

Daniel


2 Answers

Do it this way:

var result = { controllers: [], views: [], models: [] };
var dirs = ['controllers', 'views', 'models'];
var pending = 0;

dirs.forEach(function(dirname) {
    pending++;
    fs.readdir('./' + dirname, function(err, res) {
        pending--;
        if (err) throw err;
        result[dirname] = res;
        if (pending===0) goOn();
    });
});
function goOn() {
    // #1
}
like image 128
thejh Avatar answered Feb 27 '26 20:02

thejh


I believe this has something to do with the asynchronous nature of Node.js / JavaScript callbacks.

Yes, this is probably the reason why, when you try to output the content of your result variable at #1, it's empty. At the time of running at #1 data are simply not yet fetched because "fetching" action happens druing the execution of readdir's callback at #2. I would recommend to look at some of the resources about asynchronous paradigms stated in this answer in order to get the bigger/better picture of how callbacks and asynchronous programming works.

like image 45
yojimbo87 Avatar answered Feb 27 '26 19:02

yojimbo87



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!