NodeJs异步编程 - 协调并行调用 [英] NodeJs Asynchronous programming - Coordinating parallel calls

查看:252
本文介绍了NodeJs异步编程 - 协调并行调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我参考这个nodetuts教程协调NodeJs中的并行调用。
http://nodetuts.com/series/asynchronous -programming / mastering-asynchronous-programming-02.html

I was referring this nodetuts tutorial on coordinating parallel calls in NodeJs. http://nodetuts.com/series/asynchronous-programming/mastering-asynchronous-programming-02.html

有些事情需要您帮助理解。

There is something that I needed your help in understanding.

callback1,callback12,callback3是需要并行执行的函数。

callback1,callback12, callback3 are the functions that need to be executed parallelly. Each takes their own time to execute.

但它们的结果以相应的顺序存储在结果数组中

But their results are stored in the results array in the respective order

[resultofcallback1, resultofcallback2, resultofcallback3]

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

The only contract of the final callback to execute only once and show the results in a proper order, as mentioned. For that we have a Boolean calledBack to make sure it is executed only once.

请参阅

我的参数是在执行callBack1时。
内部 handleResult pending = 0 order = to 1
让我们假设这个回调花费的执行时间最少。

My argument is while executing callBack1. Inside handleResult : pending =0, order = 0, pending is incremented to 1 Let's say this callback takes the least time to execute.

这个handleResult的返回函数内部 pending减少
,使得 pending 0 。让我们说这个时候没有其他的callBacks (callback1,callback2)已经到达了他们的handlResult函数,因此挂起保留0.所以这if(!pending)assert和最后的callBack [resultofCallback1,'',''] ,只输出一个结果 callback(null,results); 其余两个为空,因为最后的回调应该只调用一次。

Inside the return function for this handleResult pending is decremented which makes pending 0. Let's say by this time no other callBacks(callback1 ,callback2) has reached their handlResult function, thus pending remains 0. So this if(!pending) assert and the final callBack is called callback(null, results); outputting only one result something like [resultofCallback1,'',''], the rest two empty, as the final callback should be called only once.

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);
}

这是一个正确的方法来协调并行调用

Is this a right approach to make coordinating parallel call Did I miss something?

推荐答案

您可以随时使用异步并行或类似的东西。

You can always use async parallel or stuff like that.

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

As for the manual implementation, you can do one of the following:

1-长时间轮询已完成任务的数量。如果#of finished tasks == total#of tasks => final callback

1- Long poll the amount of finished tasks. If # of finished tasks == total # of tasks => final callback

2-在每个回调结束时,发送一个I'm done检查我完成信号的量。如果我完成信号的数量等于任务的总数=>最终回调。

2- At the end of every individual callback, send an "I'm done" signal and check the amount of "I'm done" signals. If the amount of "I'm done" signals is equal to total number of tasks => final callback.

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

Looks like you're going with 2nd approach. Checking your code, I don't see you missing any aspect, but you have one big problem:

如果你的第一个任务完成之前,你注册第二个任务,您只需使用第一个任务的结果执行最终回调。

重述:注册任务的方式带来了高度

To restate: The way you register your tasks brings up a race condition that highly depends on the fact that you roll high enough from random timeouts so that you can register all your tasks before the ones that you registered all finish.

建议的修正:

Suggested fix: Don't start any of your tasks before you successfully register all of them.

此外,如果您在0开始待处理并执行order = pending,当你注册3个任务并且没有一个任务完成时,你会得到一个pending = 2,第二个任务完成后,第三个任务仍在进行,你执行最后的回调。

Also: If you start your pending at 0 and execute order = pending, you get a pending = 2 when you register 3 tasks and none of them finish, and after the second task finishes and the 3rd task is still under way, you execute the final callback.

这篇关于NodeJs异步编程 - 协调并行调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆