I've recently used a nice library for node.js called Kue.
I wanted to get some better understanding of what's going so I started reading the code...
I stumbled on to a piece of code and my mind went "WTF!!?!@$@!$"...
This is the code:
function get(obj) {
var pending = 0
, res = {}
, callback
, done;
return function _(arg){
switch (typeof arg) {
case 'function':
callback = arg;
break;
case 'string':
++pending;
obj[arg](function(err, val){
if (done) return;
if (err) return done = true, callback(err);
res[arg] = val;
--pending || callback(null, res);
});
break;
}
return _;
};
}
which being used like this:
exports.stats = function(req, res){
get(queue)
('inactiveCount')
('completeCount')
('activeCount')
('failedCount')
('delayedCount')
('workTime')
(function(err, obj){
if (err) return res.send({ error: err.message });
res.send(obj);
});
};
.
.
.
Are those functions on functions?!
How are they aware of each other?
What is that '_'(underscore) on the 7th row of the function?
Could someone please help me understad what's goin' on over there? :)
Functions can indeed return functions. Take this function, for example:
function func(text) {
alert(text);
return func;
}
Obviously the return value of any invocation of func will be, again, func, so you can use it like this:
func("hello")("world");
…and you'll get two alerts: first "hello", and then "world".
Next, there's something called a named function expression. You might have seen anonymous function expressions before:
doSomething(thing, function(err) {
// operation completed or something
});
That, of course, is great for simple things, but sometimes you want the function to have a name so it can refer to itself. As Kolink mentioned, if you just want to recurse, there's arguments.callee, which refers to the function currently executing, but there is another way: you can give the function a name visible only within the function while still having it be a function expression:
doSomething(thing, function myself(err) {
// ^^^^^^
// now I can refer to myself as myself!
});
An underscore is a valid identifier, so they're basically just combining these techniques in a way that may be difficult to understand.