2

これがどのように機能するかを説明してください。私はnodejsを初めて使用し、コードの設定方法を正しく理解するには非常に複雑です。

理解できないコードを小さなスニペットに分割しました。以下にコード全体を見つけることができます。

callback(function() {
  results.push(Array.prototype.slice.call(arguments));
  next();
});

上記のスニペットがわかりません。この無名関数がシリーズanon関数の次の引数になるようですか?anon関数の引数のコードは実行されますか?

function(next) { async(1, next); }

どちらが最初に実行されますか?系列関数での非同期関数の実行または次のパラメーターの実行?

ここに完全なコードを添付しました:

function series(callbacks, last) {
  var results = [];
  function next() {
    var callback = callbacks.shift();
    if(callback) {
      callback(function() {
        results.push(Array.prototype.slice.call(arguments));
        next();
      });
    } else {
      last(results);
    }
  }
  next();
}

function async(arg, callback) {
  var delay = Math.floor(Math.random() * 5 + 1) * 100;
  console.log('async with \''+arg+'\', return in '+delay+' ms');
  setTimeout(function() {
    callback(arg*2);
  }, delay);
}

function final(results) {
  console.log('Done', results);
}

series([
  function(next) { async(1, next); },
  function(next) { async(2, next); },
  function(next) { async(3, next); },
  function(next) { async(4, next); },
  function(next) { async(5, next); },
  function(next) { async(6, next); }
], final);
4

2 に答える 2

3

まず、JavaScriptでは、関数をパラメーターとして他の関数に渡すことができることを知っておいてください。これは、別の関数から返された値を渡すこととは大きく異なります。この簡単な例を見てください。

function A() {
    alert("In A"); 
}

function B(fn) {
    alert("In B");
    fn(); 
}

B(A);   // alerts "In B", then "In A".

B(A()); // alerts "In A", then "In B", 
        // (then errors because the return value from A is undefined, 
        // and thus cannot be invoked.)

したがって、コード例を最初から最後までたどるために、次のようになります...

  1. seriesは、関数の配列(callbacks)ともう1つの関数(last)をパラメーターとして受け取る関数です。最初に呼び出されます。

  2. seriesで、という名前の関数nextが定義されています(という名前の各コールバック関数のパラメーターと混同しないでくださいnext)。関数nextが呼び出されます。

  3. nextで、という名前の変数callbackが定義されています。callbacksその値は、配列の関数の1つです。変数に格納されているcallback関数は、無名関数で呼び出されます。

  4. callbackで、async関数が呼び出されます。手順3と同じ無名関数がに渡されasyncます。現在はと呼ばれていますが、これはで定義されている関数nextとは何の関係もありません。nextseries

  5. 内でasync、いくつかの計算が実行され、最終的に無名関数が(を介してsetTimeout)呼び出されます。callback関数内で呼び出されasyncます。

  6. 無名関数内で、いくつかの値がresults配列にプッシュされ、next呼び出されます。これはでnext定義された関数seriesです。

  7. 内のすべての関数が呼び出されるまで手順3〜6を繰り返しcallbacksてから、パラメーターlastfinal)の関数が呼び出されます。

泥のように澄んでいますよね?

于 2012-08-30T13:29:06.830 に答える
1

級数関数は、実行する関数のリストを取ります。この各関数は、関数である必要がある単一のパラメーター、コールバックを受け取る必要があります。seriesそのコールバックを使用して、関数が非同期作業を終了したことを認識します。

これが何をするかのステップバイステップですseries

  1. 関数のリストと名前の付いた単一のコールバックを取りますlast
  2. resultsこれらすべての関数の結果を格納する配列を作成します
  3. リストの最初のアイテムを選択し、リストから削除します
  4. アイテムが関数でない場合(リストが空の場合):
    1. 配列lastで呼び出すresults
    2. 止まる。終わったね
  5. アイテムが関数である場合は、それを呼び出して、完了したときに通知する新しいコールバックを渡します。
  6. 関数が非同期作業を実行すると、任意の数のパラメーターを使用してコールバックを呼び出す必要があります。それらのパラメータをresults配列に格納します
  7. 3に移動

基本的に、これは各ステップ間でプロセスが完了するまで待機する再帰関数です。その結果、callbacksリストで渡した各関数は、前の関数の実行が終了した後に順番に呼び出されます。

落胆しないでください。非同期コードは、経験豊富なプログラマーにとっても難しいものです。

于 2012-08-30T13:19:33.170 に答える