0

このプログラムの基本的な流れは、UDP パケットを受信し、それらに関する情報を検索し、さらに処理するために送信することです。情報は現在mongodbに保存されています。

疑似 JS は次のようなものです。

socket.on('message', function(message) {
    mongo.lookup(message, function(err, object) {
        furtherProcessing(object);
    });
});

このフローで奇妙な/迷惑な動作に気付きました。

mongodb は非同期であるため、ルックアップが応答するのを待っている間に、プログラム フローが次のパケットに切り替わることがわかりました。これは、多数のパケットが到着した場合、複数の mongodb リクエストがインターリーブされる可能性があることを意味します (つまり、プログラムは複数のパケットのコールバックを待機しています)。残念ながら、mongo からの応答はランダムな順序 (またはおそらく mongo によって満たされる順序) であるように見えます。つまり、オブジェクトがfurtherProcessing関数に渡されるまでに、順序が変更される可能性があります。

非同期リクエストで FIFO の順序付けを強制する方法はありますか? つまり、送信されたすべてのオブジェクトfutherProcessingがソケットから受信された順序と同じであることを保証する方法はありますか?

4

1 に答える 1

1

ある種のキュー配列を使用して、自分でロジックをコーディングする必要があると思います。

メッセージを受信順に保存するだけで、非同期タスクのいずれかが完了するたびに、そのタスクに完了のフラグを付けて、完了したキューの先頭にあるすべてのものを後続の処理に送信します。

このように、メッセージ 2、3、4 が完了すると、メッセージ 1 が完了するまで送信されません。次に、4 つすべてが同じランループで飛行します。

// outer queue to save messages
var queue = [];

socket.on('message', function(message) {

  // packet comes in, add it to the queue
  queue.push(message);

  // start the async lookup
  mongo.lookup(message, function(err, object) {

    // mark message compelte
    message.complete = true;

    // loop through the queue
    for (var i = 0; i < queue.length; i++) {

      // is the message task completed?
      if (queue[i].complete) {

        // further process this item
        furtherProcessing(queue[i]);


      // Found the first incomplete message!
      } else {

        // remove processed items so far from the queue
        // by making a new array from this index onward
        queue = queue.slice(i);

        // stop the loop
        return;
      }
    }
  }
})

作業例: http://jsfiddle.net/Khp3V/

この例の非同期ルックアップは、0 ミリ秒から 500 ミリ秒の間でランダムにかかるため、順不同が保証されます。ただし、コンソールを見ると、処理された順にリストされます。

于 2013-07-15T18:08:16.110 に答える