Why do I need to have anonymous function in the setTimeout for this code to work?

I'm reading a tutorial for Nodejs, but I can't understand this snippet of code, please explain it to me.

function async(arg, callback) {
  console.log('do something with \''+arg+'\', return 1 sec later');
  setTimeout(function() { callback(arg * 2); }, 1000);
}
function final() { console.log('Done', results); }

var items = [ 1, 2, 3, 4, 5, 6 ];
var results = [];
var running = 0;
var limit = 2;

function launcher() {
  while(running < limit && items.length > 0) {
    var item = items.shift();
    async(item, function(result) {
      results.push(result);
      running--;
      if(items.length > 0) {
        launcher();
      } else if(running == 0) {
        final();
      }
    });
    running++;
  }
}

launcher();

This code produces run 2x then pause for a second then run 2x again until there is no item in the items array.

But when I removed the anonymous function in the setTimeout:

setTimeout(callback(arg*2), 1000);

Then the code runs with out stopping any second. Why?

Then the code runs with out stopping any second. Why?

Because instead of passing a function to setTimeout, you are passing the return value of a function call to it.

The function call executes immediately, and then setTimeout does nothing with the return value because it (presumably) isn't a string or a function.

Don't remove the anonymous function wrapper.

The reason the anonymous delegate is needed is because setTimeout expects an object of type function as it's first argument.

So you can either give it just a pre-defined function name directly:

function foo()
{
//do something
}

setTimeout(foo, 1000);

Or a delegate:

setTimeout(function(){/*dosomething*/}, 1000);

But this:

setTimeout(foo(param), 1000);

Is invalid because foo(param) isn't semantically correct in this context.

The alternative is to do something like:

setTimeout("foo(param);", 1000);

Because setTimeout will also accept a string of a function, but this is a bad idea because you lose the current scope and it's a pain to debug.