我花了几个小时阅读SO,其答案如Meteor: Calling an asynchronous function inside a Meteor.method and returning the result
不幸的是,我仍然无法管理用户光纤或期货。
我正在尝试做一些相当简单的事情(我想!)。
创建用户时,根据异步方法的结果向用户对象添加变量。因此,想象一下,如果您将在名为BANK的第三方数据库服务器上调用我的异步方法,这可能需要几秒钟才能返回。
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;
});
所以上面发生的是调用BANK方法,但是当它返回时代码已经移动并且从不调用_.extend。
我尝试将返回调用放在光纤内部,这只会让事情变得更糟:它永远不会返回用户。它确实如此,但是太晚了3秒,所以下游的一切都在拯救。
感谢您的帮助!
答案 0 :(得分:5)
回答我自己的问题,希望将来可以帮助一些人。这是基于Avital Oliver和David Glasser的出色建议来看看Mike Bannister的meteor-async.md。您可以在此处阅读: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();
}
我相信有一种更好的方法可以解决这个问题,直接将BANK API包装在npm包本身的Futures中,如本例所示(来自Avital Oliver):https://github.com/avital/meteor-xml2js-npm-demo/blob/master/xml2js-demo.js
我希望它有所帮助!
答案 1 :(得分:1)
在服务器端代码上使用this.unblock()。
从Meteor 1.0文档:“允许来自此客户端的后续方法开始在新光纤中运行。在服务器上,来自给定客户端的方法一次运行一个。来自客户端的第N + 1次调用将无法启动直到第N个调用返回。但是,你可以通过调用this.unblock来改变它。这将允许第N + 1次调用开始在新光纤中运行。“
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;
}
}});
答案 2 :(得分:0)
方法调用在服务器端使用同步样式(请参阅此处的{sync call'http://docs.meteor.com/#meteor_call),这是此create用户方法运行的地方 - 您应该可以执行类似
的操作Accounts.onCreateUser(function(options, user) {
user.balance = Meteor.call('getBankBalance', params);
return user;
});
答案 3 :(得分:0)
非常感谢你的工作,这个解决方案更适合Meteor项目,因为默认安装了Fibers模块。 mrt add npm也有一个方法 - > Meteor.sync。对于任何nodeJS项目,还有一个基于Fibers的模块,其名称为Fibrous