0

I have a nodejs code that has callback and I couldn't understand how it works. Can someone explain it

function readJSONIntoArray(directory, array, callback) 
{
    var ending = 'json';
    fs.readdir(directory, function (err, files) 
    {
        if (err)
           throw err;
        var fileCnt = files.length;
        files.forEach(function (file) 
        {
            if (endsWith(file, '.' + ending)) 
            {
                file = file.substring(0, file.length - (ending.length + 1));
                var fileContent = require(path.join(directory, file));
                array.push(fileContent);
                log.info('Read file: ' + file);
            }
            fileCnt--;
            if (fileCnt === 0 && typeof callback === 'function') 
            {
                callback();
            }
        });
    });
}

Here the callback is empty so I guess no value is being returned. But in actual output the array is returned. I couldn't understand an empty callback can return a array.

Function call:readJSONIntoArray(profilefolder, profiles, setProfileDescriptions);

Definition of setProfileDescriptions is separate.

function setProfileDescriptions() 
{
    profiles = bubblesort(profiles, 'order');
}

Inside the setProfileDescriptions the profile array is populated with the json data from the file read in the read function. Can someone explain how the 3rd argument in the readJSONIntoArray function call is recognized as a function and the array profiles is returned?

1
  • 1
    profiles is not given to setProfileDescription as a parameter. However the variable might be global, if so you can access it because of that. Commented Mar 16, 2016 at 9:15

2 Answers 2

2

You're right that readJSONIntoArray does't return anything in it's callback. Instead it appends new data to the second argument array, thus mutating it.

So, readJSONIntoArray was meant to be used in the following way:

var content = []; // empty array to accumulate data from readJSONIntoArray function
readJSONIntoArray('some directory', content, function () {
  // content is full of data now
  doSomething(content);
});

Though I must point out that this is not a common pattern in node.js, and that it should be avoided because it's too confusing.

In fact, there are several things in readJSONIntoArray implementation which were done wrong:

  • functions should never mutate their arguments;
  • async functions should not throw errors, they should return them in callback instead;
  • any data produced by the function should also be returned in callback.
Sign up to request clarification or add additional context in comments.

Comments

0
var globalArray=[];
function readFunction(path,globalArray,callbackFunction){
    globalArray.push(path);
    callbackFunction();
}
function callbackFunction(){
    //globalArray was global so i can call here
    console.log(globalArray);
}

readFunction('filePath',globalArray,callbackFunction);

consider above code because the 'globalArray' declared as global i can access inside the callback function

6 Comments

In your example globalArray is an argument of readFunction and not a global variable.
but i declare the globalArray first. so it should be consider as global variable right?
No, inside of readFunction it's shadowed by the local variable. So, your "global" globalArray will not be affected by readFunction unless it's passed as an argument. And declaring it before readFunction does absolutely nothing in your example.
so if its shadowed by the 'readfunction' as local variable. then i should not able to log the 'globalArray' value to console right?. but i can able to log the value
If you refer to console.log inside of callbackFunction, then you're logging the "global" globalArray, because it's not shadowed there. As for readFunction, you're passing exactly the same globalArray as an argument there, but inside of the function you're still addressing a local variable. It's just the way you called readFunction which made it the very same array as the "global" globalArray.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.