Kevin Lee
Kevin Lee

Reputation: 1089

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?

Upvotes: 1

Views: 191

Answers (2)

PhonicUK
PhonicUK

Reputation: 13854

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.

Upvotes: 0

Quentin
Quentin

Reputation: 943516

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.

Upvotes: 3

Related Questions