質問

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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top