为什么我需要在setTimeout中使用匿名函数才能使此代码生效?

时间:2012-08-30 08:03:06

标签: javascript node.js

我正在阅读Nodejs的教程,但我无法理解这段代码,请向我解释。

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();

此代码生成run 2x,然后暂停一秒,然后再次运行2x,直到items数组中没有项目。

但是当我在setTimeout中删除了匿名函数时:

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

然后代码运行而不停止任何秒。为什么呢?

2 个答案:

答案 0 :(得分:3)

  

然后代码运行而不停止任何秒。为什么呢?

因为您不是将函数传递给setTimeout,而是将函数调用的返回值传递给它。

函数调用立即执行,然后setTimeout对返回值不执行任何操作,因为它(可能)不是字符串或函数。

不要删除匿名函数包装器。

答案 1 :(得分:0)

需要匿名委托的原因是因为setTimeout需要一个function类型的对象作为它的第一个参数。

所以你可以直接给它一个预定义的函数名:

function foo()
{
//do something
}

setTimeout(foo, 1000);

或代表:

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

但是这个:

setTimeout(foo(param), 1000);

无效,因为在此上下文中foo(param)在语义上不正确。

另一种方法是做类似的事情:

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

因为setTimeout也会接受一个函数的字符串,但这是一个坏主意,因为你丢失了当前的范围,调试很麻烦。