How to call the async method from Meteor's own callbacks?

I just spent several hours reading SO with answers like Meteor: calling an asynchronous function inside Meteor.method and returning the result

Unfortunately, I still have not been able to use user threads or futures.

I'm trying to make something pretty simple (I think!).

When creating a user, add a variable to the user object based on the result of the asynchronous method. So imagine if you call my asynchronous method on a third-party db server called BANK, which can take a few seconds.

Accounts.onCreateUser(function(options,user){ var Fiber = Npm.require("fibers"); Fiber(function() { BANK.getBalance(function(err, theBalance) { if (err) return console.log(err); _.extend(user,{ balance: theBalance; }); }); }).run(); return user; 

});

So what happens in the above is that the BANK method is called, but by the time it returns, the code has already been moved, and _.extend is never called.

I tried to place a callback inside Fiber, which only exacerbated the situation: it never returns the user. Well, yes, but 3 seconds is too late, so by then everyone downstream had been saved.

Thanks for the help!

+4
source share
4 answers

Answering my own question, which I hope will help some people in the future. It is based on the excellent advice of Avital Oliver and David Glasler to look at Mike Bannister meteor-async.md. You can read it here: https://gist.github.com/possibilities/3443021

 Accounts.onCreateUser(function(options,user){ _.extend(user,{ balance: getBalance(), }); return user; }); function getBalance() { var Future = Npm.require("fibers/future"); var fut = new Future(); BANK.getBalance(function(err, bal) { if (err) return console.log(err); fut.return(bal); }); return fut.wait(); } 

I believe that there is an even better way to handle this, which is directly related to packaging the BANK API in Futures in the npm package itself according to this example (from Avital Oliver): https://github.com/avital/meteor-xml2js- npm-demo / blob / master / xml2js-demo.js

Hope this helps!

+5
source

Use this.unblock () for server-side code.

From the Meteor 1.0 documentation: β€œAllow the subsequent method from this client to start working in a new fiber. On the server, the methods from the specified client are launched one at a time. The N + 1st call from the client does not start until the Nth call returns, but you you can change this by calling this.unblock. This will allow the N + 1st call to run in the new fiber. "

 Meteor.methods({checkTwitter: function (userId) { check(userId, String); this.unblock(); try { var result = HTTP.call("GET", "http://api.twitter.com/xyz", {params: {user: userId}}); return true; } catch (e) { // Got a network error, time-out or HTTP error in the 400 or 500 range. return false; } 

}});

+1
source
In method calls

the synchronization style is used (see "sync call" here http://docs.meteor.com/#meteor_call ) on the server side where this creates the user method works - you should be able to do something like

 Accounts.onCreateUser(function(options, user) { user.balance = Meteor.call('getBankBalance', params); return user; }); 
0
source

Thank you so much that work. This solution is better for Meteor projects because the Fibers module is installed by default. mrt add npm also has a method for this -> Meteor.sync. For any nodeJS projects, there is another module based on Fibers, its name is Fibrous

Link: https://github.com/goodeggs/fibrous

0
source

All Articles