如何从Meteor自己的回调调用异步方法?

如何从Meteor自己的回调调用异步方法?,meteor,node-fibers,Meteor,Node Fibers,我刚刚花了几个小时阅读了一些答案,比如 不幸的是,我仍然没有成功地使用光纤,或者在这方面的未来 我正在尝试做一些相当简单的事情(我想!) 创建用户时,根据异步方法的结果向用户对象添加变量。所以想象一下,如果您愿意,我的异步方法是在第三方数据库服务器BANK上调用的,这可能需要几秒钟才能返回 Accounts.onCreateUser(function(options,user){ var Fiber = Npm.require("fibers"); Fiber(function() {

我刚刚花了几个小时阅读了一些答案,比如

不幸的是,我仍然没有成功地使用光纤,或者在这方面的未来

我正在尝试做一些相当简单的事情(我想!)

创建用户时,根据异步方法的结果向用户对象添加变量。所以想象一下,如果您愿意,我的异步方法是在第三方数据库服务器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方法,但是当它返回代码时,代码已经移动,并且永远不会调用u.extend

我试着把回电放在光纤里,结果只会让事情变得更糟:它永远不会回用户。的确如此,但晚了3秒,所以到那时下游的一切都已恢复正常


谢谢你的帮助

方法调用在服务器端使用sync样式(请参阅此处的“sync call”),这是create user方法运行的地方-您应该能够执行以下操作

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

回答我自己的问题,希望将来能对一些人有所帮助。这是基于Avital Oliver和David Glasser的优秀建议,让我们看看Mike Bannister的meteor-async.md。你可以在这里阅读:

我相信有一种更好的方法来处理这个问题,即直接将银行API包装在npm包本身的期货中,如以下示例所示(来自Avital Oliver):


我希望有帮助

非常感谢您的工作,这个解决方案更适合Meteor项目,因为默认情况下安装了光纤模块。mrt add npm对此也有一个方法->Meteor.sync。对于任何nodeJS项目,都有一个基于Fibers的其他模块,其名称是Fibers

参考:

在服务器端代码上使用此.unblock()

来自Meteor 1.0文档:允许来自此客户端的后续方法开始在新光纤中运行。在服务器上,来自给定客户端的方法一次运行一个。在第N次调用返回之前,客户端的第N+1次调用不会启动。但是,您可以通过调用this.unblock来更改此设置。这将允许第N+1次调用开始在新光纤中运行。”


}})

向那个在没有解释的情况下否决了我的问题的家伙致意……可能是个PHP迷。嗨,内特,遗憾的是调用方法对我不起作用,因为Meteor.call('getBalance',param)将只调用服务器API调用的现有实现,该调用是异步的,需要几秒钟才能返回,等等。无论如何,谢谢!实际上,若我只调用Meteor.call('BANK.getBalance'),将在此基础上进行扩展,它似乎正确地处理了第一次呼叫,而每次后续呼叫都会一次又一次地返回相同的余额。不知道为什么。那么,如果发生错误会发生什么?如果未来永远不会回来会发生什么?有没有拒绝未来的方法?是的,如果有人能对优雅的错误处理发表评论那就太好了!现在因为你不能在将来抛出Meteor.throw(),我必须在调用它的函数中进行错误处理…非常难看:(
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();
}
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;
 }