Calling result of a function call as a function in javascript/node.js

I recently came across some node.js code that has an anonymous function enclosed in parentheses immediately after a function call. Could somebody please explain to me what is going on with the syntax here?

var fs = require('./continuable-style-fs');

fs.readFile('mydata.txt')(function (text) {
  // Do something
  console.log(text);
}, function (error) {
  // Handle error
  throw error
});

continuable-style-fs is returning versions of the built-in fs methods that return functions instead of accepting a callback as an argument.

With that in mind, the callback is being passed to the function returned by fs.readFile(). The callback is then called when the read is complete, just like the original fs.readFile() would.

When looking at the code for continuable-style-fs, the second function passed is the function that receives errors. This is more promise-like than the "error-first" callback approach of async node core methods.

It means that fs.readFile('mydata.txt') returns a function, which is immediately invoked.

It might make more sense to look at it like so...

var fs = require('./continuable-style-fs');

var fn = fs.readFile('mydata.txt');

fn(function (text) {
  // Do something
  console.log(text);
}, function (error) {
  // Handle error
  throw error
});

Without you posting the function require() it's a little hard to tell since we don't know exactly what that returns. If you provide more info I'm sure I can figure it out, otherwise I'm slightly guessing at the answer right now. OK so here it goes:

in JavaScript you can have an anonymous function that takes a parameter. You would initiate that function as follows:

(function (variable){
 ...
 ...
})(myVariable);

So if required() returns an object, then fs.readFile () would be a method attached to that object (through prototyping). In this case it looks like it's a method that itself returns an anonymous function that will then receive either the variable from the //Do something section or it will receive the error/variable from the //Handle error

So in the end the you'll have

fs.readFile('mydata.txt')(someVariable);

Which if readFile does return an anonymous function then it will look like:

(function foo (variable){})(someVariable);

This as another answers mentions is simply a slightly different approach to using callbacks. I hope that helps, and is clear.

What's happening is this, the following code:

fs.readFile('mydata.txt')(function (text) {
  // Do something
  console.log(text);
}, function (error) {
  // Handle error
  throw error
});

Can be translated to this:

var file_reader = fs.readFile('mydata.txt');
file_reader(function (text) {
  // Do something
  console.log(text);
}, function (error) {
  // Handle error
  throw error
});

Which can then be translated to this:

function read_file_handler (text) {
    // Do something
    console.log(text);
}

function file_error_handler (error) {
    // Handle error
    throw error
}

var file_reader = fs.readFile('mydata.txt');

file_reader(read_file_handler, file_error_handler);

Basically, javascript allows you to:

  1. Treat functions as data

  2. Immediately use the result of any expression or function call

Number 2 is interesting. Because it allows you to do things like this:

function foo () {
    return "a,b,c";
}
var abc_array = foo().split(',');

Note that in the example above split is a String method but we can call it immediately after foo() because it returns a string.

Similarly we can do this:

function foo () {
    return function () {console.log('hello')}
}
foo()();

Here calling foo() returns a function. We can assign it to a variable and call that but we can also call it immediately as we do above.