Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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 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]

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.

Please see the code below

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.

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
126 views
Welcome To Ask or Share your Answers For Others

1 Answer

You can always use async parallel or stuff like that.

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

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

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:

If your first task finishes before you register the second task, you execute the final callback only with the result of the first task.

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.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...