2

この質問は重複する可能性があります。私は node.js と非同期プログラミング回文の初心者です。私はグーグルで検索し、これに関する多くの例を見てきましたが、まだ少し混乱しています.

OK、Google検索から私が理解しているのは、すべてのコールバックが非同期で処理されるということです。たとえば、node.js api からreadfile関数を取得してみましょう

fs.readFile(filename, [options], callback) // ここでのコールバックは非同期で処理されます fs.readFileSync(filename, [options])

  var fs = require('fs');

    fs.readFile('async-try.js' ,'utf8' ,function(err,data){
        console.log(data);   })

    console.log("hii");

上記のコードは、最初に hii を出力し、次にファイルの内容を出力します。

だから、私の質問は次のとおりです。

  1. すべてのコールバックは非同期で処理されますか?
  2. 以下のコードは非同期ではありません。なぜ、どのように作成すればよいですか?

    function compute(callback){
     for(var i =0; i < 1000 ; i++){}
     callback(i);
    
    }
    
    function print(num){
     console.log("value of i is:" + num);
    }
    
    
    compute(print);
    console.log("hii");
    
4

4 に答える 4

4

すべてのコールバックは非同期で処理されますか?

必ずしも。NodeJS では、実行時間の長いタスク (通常は IO 操作) が終了した後に関数の実行 (継続) を再開することがまさにその目的であるため、一般的にはそうです。ただし、同期コールバックを自分で作成したため、ご覧のとおり、常に非同期であるとは限りません。

以下のコードは非同期ではありません。なぜ、どのように作成すればよいですか?

コールバックを非同期で呼び出す場合は、Node に「時間があるときに」実行するように指示する必要があります。つまり、Node が進行中の実行を終了するまで、コールバックの実行を延期します。

function compute(callback){
 for (var i = 0; i < 1000; i++);

 // Defer execution for later
 process.nextTick(function () { callback(i); });
}

出力:

hii
value of i is:1000

非同期コールバックの仕組みの詳細については、process.nextTick の仕組みを説明しているこのブログ投稿をお読みください。

于 2013-06-13T15:01:28.557 に答える
3

いいえ、それは通常の関数呼び出しです。

強制されない限り、コールバックは非同期になりません。setTimeoutこれを行う良い方法は、0 ミリ秒以内に呼び出すことです。

setTimeout(function() { 
   // Am now asynchronous
}, 0);

通常、コールバックは、呼び出し元の関数がサーバー上で新しい要求を行う場合 (たとえば、新しいファイルを開く場合) に非同期になり、完了するのを待っている間に実行を停止しても意味がありません。

于 2013-06-13T14:55:09.233 に答える
2

以下のコードは非同期ではありません。なぜ、どのように作成すればよいですか?

function compute(callback){
  for(var i =0; i < 1000 ; i++){}
  callback(i);
}

あなたのコードは、「何かを 1000 回実行し、すべてが完了したらコールバックを使用する必要がある」と言おうとしていると仮定します。

これを想像してみてください:

function compute(callback){
  for(var i =0; i < 1000 ; i++){
    DatabaseModel.save( function (err, result) {
      // ^^^^^^ or whatever, Some async function here.
      console.log("I am called when the record is saved!!");
    });
  }
  callback(i);
}

この場合、 for ループは save 呼び出しを実行し、それらが完了するのを待ちません。したがって、あなたの例では、(タイミングによっては)次のような出力が得られる場合があります

I am called when the record is saved
hii
I am called when the record is saved
...

すべてが完全に完了したとき (1000 レコードすべてがデータベースに保存されたとき) にのみ計算メソッドがコールバックを呼び出すようにするには、async Node パッケージを調べます。これはこれを簡単に行うことができ、多くの非同期問題のパターンを提供します Node.jsで直面します。

したがって、計算関数を次のように書き直すことができます。

function compute(callback){
  var count = 0
  async.whilst(
     function() { return count < 1000 },
     function(callback_for_async_module) {
        DatabaseModel.save( function (err, result) {
            console.log("I am called when the record is saved!!");
            callback_for_async_module();
            count++;
        });
     },
     function(err) {
       // this method is called when callback_for_async_module has
       // been called 1000 times

       callback(count);
  );
  console.log("Out of compute method!");
}

計算関数のコールバック パラメータは、 の後で呼び出されることに注意してくださいconsole.log("Out of compute method")computeこの関数は非同期になりました。アプリケーションの残りの部分は完了するまで待機しません。

于 2013-06-13T15:15:56.530 に答える
0

すべてのコールバック呼び出しを 1 ミリ秒のタイムアウト内に置くことができます。これにより、スレッドが解放され、すべての同期タスクが完了したときに最初に実行され、次にプロセッサが実行したいタイムアウトのスタックを処理します。

于 2013-06-13T14:53:31.513 に答える