1

What will be the performant solution for this problem where I want to make some async calls, wait in last until all the calls are completed, then return the result.

function parseAndMatch(arg1, arg2){
   async.all([
      asyncCall1(arg1, arg2),
      asyncCall2(arg1, arg2)]
   ).then( result => {
      //do something with result;
      return finalResult;
   });
}

I tried to fit npm deasync, asyncawait, bluebird, and async packages to solve this problem. But I couldn't find the solution.

Kevin B
  • 94,570
  • 16
  • 163
  • 180
Amit Kumar Gupta
  • 7,193
  • 12
  • 64
  • 90
  • well... the `then return the result.` part is pretty much impossible. Otherwise, the answer is yes. – Kevin B Jan 27 '17 at 18:46
  • possible dupe? http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call?rq=1 – Kevin B Jan 27 '17 at 18:49
  • @KevinB I found that question. But as it was for frontend, and I was trying to implement this in nodejs server side application, I thought to ask separately. – Amit Kumar Gupta Jan 27 '17 at 19:10
  • Teh concept is the same for both ends, javascript is javascript – Kevin B Jan 27 '17 at 19:29
  • 1
    Take a look at this answer: http://stackoverflow.com/a/41540117/1464130 it provides an example on parallel or sequential async calls – amaksr Jan 27 '17 at 19:46

3 Answers3

3

In JavaScript multiple asynchronous operations can be handled by using all method on the Promise object. This does not require the use of libraries.

Promise.all returns a Promise and takes an iterable containing multiple Promises that require resolution. Once all Promises in the iterable have resolved the Promise returned by calling Promise.all resolves. If any Promise in the iterable rejects, the Promise returned by Promise.all immediately rejects.

Promise.all resolves with an iterable of all the resolution values of the Promises given to it. Promise.all rejects with the value of the Promise given in the iterable that rejected.

Taking your example, you would use Promise.all like this:

function parseAndMatch(arg1, arg2){
  return Promise.all([
    asyncCall1(arg1, arg2),
    asyncCall2(arg1, arg2),
  ]);
}

parseAndMatch()
  .then(doSomethingElse)
  .catch(handleRejection);

Further reading

Wing
  • 8,438
  • 4
  • 37
  • 46
1

On the basis of @wing answer's I solved this problem using native Promise and npm deasync library. But I'm not sure how efficient and performant it is.

function parseAndMatch(callback) {
  return Promise.all([
      new Promise(function(resolve, reject) {
            var sum = 1;
            for (var i = 0; i < 10000; i++) {
                sum++;
            }
            return resolve(sum);
      }),
      new Promise(function(resolve, reject) {
            var sum = 1;
            for (var i = 0; i < 90000; i++) {
                sum++;
            }
            return resolve(sum);
      }),
  ]);
}

function joinAndReturn(){
    var done = false;
    var result;
    parseAndMatch().then((results) => {
        result = results[0] + results[1];
        done = true;
    });
    deasync.loopWhile(function(){return !done;});
    return result;
}

console.log(joinAndReturn());//100002
Pineda
  • 7,435
  • 3
  • 30
  • 45
Amit Kumar Gupta
  • 7,193
  • 12
  • 64
  • 90
  • The reason I used Promise in `parseAndMathc` function, because some parallel functions can be async. – Amit Kumar Gupta Jan 27 '17 at 19:54
  • Are you using `deasync.loopWhile` to pause the `joinAndReturn` function until `parseAndMatch` has resolved? If you are native JavaScript can handle this – see [async functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function). – Wing Jan 28 '17 at 22:11
  • may be using that can improve the performance. Right now I'm trying to use callbacks or other alternatives. Because above code can impact the performance badly. – Amit Kumar Gupta Jan 29 '17 at 00:06
  • Although I found some alternate ways to code where I'm not falling in this situation, I'm marking this is an answer until some good answer is given. – Amit Kumar Gupta Feb 16 '17 at 06:09
  • Does my [answer](http://stackoverflow.com/a/41901356/3050293) or my [comment](http://stackoverflow.com/questions/41900886/join-all-async-calls-to-return-some-result/41901356#comment71012158_41901919) regarding [async functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) not resolve your issue? If they don't please share more details on what trouble you are having. If they do, at least upvote answers that have helped you. – Wing Feb 16 '17 at 10:34
-1

If asyncCall1 and asyncCall2 return Promises. Using bluebird:

function parseAndMatch(arg1, arg2){
  return Promise.join(
      asyncCall1(arg1, arg2), 
      asyncCall2(arg1, arg2), 
      (result1, result2) => {
        //do something with result1, result2;
        return finalResult;
  });
}

If they support callback. Using async.parallel:

function parseAndMatch(arg1, arg2, callback) {
  async.parallel([
      callback => {
        asyncCall1(arg1, arg2, callback);
      },
      callback => {
        asyncCall2(arg1, arg2, callback);
      },
    ], (err, results) => {
        if (err)
          return callback(err);
        //do something with result[0], result[1];
        return callback(null, results);
    })
}
Sangharsh
  • 2,999
  • 2
  • 15
  • 27