NodeJs 异步编程 - 协调并行调用

NodeJs Asynchronous programming - Coordinating parallel calls

本文关键字:并行 调用 协调 异步 编程 NodeJs      更新时间:2023-09-26

我指的是这个nodetuts教程,关于在NodeJs中协调并行调用。http://nodetuts.com/series/asynchronous-programming/mastering-asynchronous-programming-02.html

有些事情我需要你的帮助来理解。

callback1、callback12、callback3 是需要并行执行的函数。每个都需要自己的时间来执行。

但是它们的结果按各自的顺序存储在结果数组中

[resultofcallback1, resultofcallback2, resultofcallback3]

最终回调的唯一只执行一次并以正确的顺序显示结果的合约,如前所述。为此,我们有一个Boolean calledBack来确保它只执行一次。

请参阅下面的代码

我的论点是在执行callBack1时。内handleResultpending =0order = 0, pending is incremented to 1假设此回调执行所需的时间最少。

在此句柄的返回函数内部结果pending is decremented这使得pending 0.假设此时没有其他 callBacks (callback1 ,callback2) 到达它们的 handlResult 函数,因此挂起仍为 0。所以这个 if(!pending) 断言和最终回调被调用callback(null, results);只输出一个结果,类似于 [resultofCallback1,'',''] ,其余两个为空,因为最终回调应该只调用一次。

module.exports = function composedCall(args, cb){
  var pending = 0;
  var results = [];
  var calledBack = false;
  callback1(args,handleResult());
  callback2(args,handleResult());
  callback3(args,handleResult());
  function handleResult(){
    var order = pending;
    pending ++;
    return function(err, result){
      pending --;
      if(err){
        callback(err);
      }else{
        results[order] = result;
        if(!pending){
          callback(null, results);
        }
      }
    }
  }
  function callback(err, value){
    if(! calledBack){
      calledBack = true;
      cb(err, value)
    }
  }
}

function callback1(args ,callback){
  setTimeout(callback, randomTimeout(), null, 1);
}
function callback2(args ,callback){
  setTimeout(callback, randomTimeout(), null, 2);
}
function callback3(args ,callback){
  setTimeout(callback, randomTimeout(), null, 3);
}
//utils
function randomTimeout(){
  return Math.floor(Math.random() * 1e3);
}
function randomValue(){
  return Math.floor(Math.random() * 1e10);
}

这是进行协调并行调用的正确方法我错过了什么吗?

你总是可以使用异步并行或类似的东西。

对于手动实现,您可以执行以下操作之一:

1-长时间轮询已完成任务的数量。如果 # 已完成的任务 == 任务总数 # => 最终回调

2-在每次回调结束时,发送"我完成了"信号并检查"我完成了"信号的数量。如果"我完成了"信号的数量等于任务总数 => 最终回调。

看起来您要采用第二种方法。检查您的代码,我没有看到您缺少任何方面,但是您有一个大问题:

如果第一个任务

在注册第二个任务之前完成,则仅使用第一个任务的结果执行最终回调。

重述:注册任务的方式会产生一个争用条件,该条件在很大程度上取决于您从随机超时中滚得足够高的事实,以便您可以在注册的所有任务完成之前注册所有任务。

建议的解决方法:在成功注册所有任务之前,不要启动任何任务。

另外:如果你从 0 开始挂起并且执行顺序 = 挂起,则当您注册 3 个任务并且没有一个完成时,您会得到一个挂起 = 2,并且在第二个任务完成并且第三个任务仍在进行中后,您执行最终回调。