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/

此示例中的异步查找将随机占用 0ms 到 500ms 之间,这确保了无序性。但是,如果您查看控制台,它会在处理它们时按顺序列出它们。

于 2013-07-15T18:08:16.110 回答