k.chao.0424
k.chao.0424

Reputation: 1191

Meteor server asynchronous method calls and using the return results

I have a method that does a really heavy computation on the server-sider, I need to call this method twice and use the result from these calls to do another computation:

combinationCalc: function(val1, val2) {
  var result1 = heavyCompute(val1);
  var result2 = heavyCompute(val2);

  return anotherComputation(result1, result2);
}

The value for result2 does not depend on value for result1, how can I execute these two computations asynchronously?

Upvotes: 1

Views: 276

Answers (3)

k.chao.0424
k.chao.0424

Reputation: 1191

I wanted to share my own solution that I found through some research. This requires using NPM package fiber/future

Future = Meteor.npmRequire('fibers/future');

combinationCalc: function(val1, val2) {
  var fut1 = new Future();
  var fut2 = new Future();

  heavyCompute(val1, fut1);
  heavyCompute(val2, fut2);

  var result1 = fut1.wait();
  var result2 = fut2.wait();

  return anotherComputation(result1, result2);
}


heavyCompute(val, fut) {
  // ALL THE COMPUTES!
  fut.return(compute_result);
}

I wanted to have a single point of entry on the server, and as little confusing code as possible.

Upvotes: 1

Daniel Kao
Daniel Kao

Reputation: 11

Using Meteor methods and session variables, you can asynchronously call meteor methods, save the results into session variables, and perform your second method call when both parameters are ready.

combinationCalc: function(val1, val2) {

  // Calls heavyCompute on val1
  Meteor.call('heavyCompute', val1, function(error, result) {
    Session.set('result1', result);
    // if heavyCompute on val2 finished first
    if(Session.get('result1') && Session.get('result2'))
      Meteor.call('anotherComputation', Session.get('result1'), Session.get('result2'), function(error, result) {
         Session.set('answer', result);
      });
  });

  // Calls heavyCompute on val2
  Meteor.call('heavyCompute', val2, function(error, result) {
    Session.set('result2', result);
    // if heavyCompute on val1 finished first
    if(Session.get('result1') && Session.get('result2'))
      Meteor.call('anotherComputation', Session.get('result1'), Session.get('result2'), function(error, result) {
         Session.set('answer', result);
      });
  });
}

Then, just call Session.get('answer'); wherever you want to use the result.

To minimize redundant code, you can put checking for undefined inside the anotherComputation method itself.

Upvotes: 0

255kb - Mockoon
255kb - Mockoon

Reputation: 6974

You can use Meteor methods which are called from the client and run asynchronously.

First declare the methods on the server:

Meteor.methods({
  firstMethod: function (arg) {
    this.unblock();
    //do stuff
  },
  secondMethod: function (arg) {
    this.unblock();
    //do stuff
  }
});

Note the use of this.unblock(); which allows a method call from the client to be run without waiting for the previous call (by default only one method can run at a time).

Then, call the method from the client (you may also call them from the server):

Meteor.call('firstMethod', arg, function(error, result() {
  //do something with the result
});
Meteor.call('secondMethod', arg, function(error, result() {
  //do something with the result
});

Upvotes: 0

Related Questions