1

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を生成し、1秒間一時停止してから、items配列にitemがなくなるまで2xを再度実行します。

しかし、setTimeoutで匿名関数を削除すると:

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

次に、コードは1秒も停止せずに実行されます。なんで?

4

2 に答える 2

3

次に、コードは1秒も停止せずに実行されます。なんで?

関数をに渡す代わりに、関数呼び出しsetTimeoutの戻り値をに渡すためです。

関数呼び出しはすぐに実行され、setTimeout(おそらく)文字列でも関数でもないため、戻り値には何もしません。

匿名関数ラッパーを削除しないでください。

于 2012-08-30T08:17:45.757 に答える
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は関数の文字列も受け入れるためですが、現在のスコープが失われ、デバッグが面倒になるため、これはお勧めできません。

于 2012-08-30T08:14:26.717 に答える