8

如何让客户端 method.call 等待异步函数完成?目前它到达函数的末尾并返回未定义。

客户端.js

Meteor.call( 'openSession', sid, function( err, res ) {
    // Return undefined undefined
    console.log( err, res ); 
});

服务器.js

Meteor.methods({
    openSession: function( session_id ) {
        util.post('OpenSession', {session: session_id, reset: false }, function( err, res ){
            // return value here with callback?
            session_key = res;
        });
     }
});
4

3 回答 3

6

最近版本的 Meteor 提供了未记录Meteor._wrapAsync的函数,它将带有标准(err, res)回调的函数转换为同步函数,这意味着当前的 Fiber 产生直到回调返回,然后使用 Meteor.bindEnvironment 来确保您保留当前的 ​​Meteor 环境变量(比如Meteor.userId())

一个简单的用法如下:

asyncFunc = function(arg1, arg2, callback) {
  // callback has the form function (err, res) {}

};

Meteor.methods({
  "callFunc": function() {
     syncFunc = Meteor._wrapAsync(asyncFunc);

     res = syncFunc("foo", "bar"); // Errors will be thrown     
  }
});

您可能还需要使用function#bind确保asyncFunc在包装之前使用正确的上下文调用它。有关更多信息,请参阅:https ://www.eventedmind.com/tracks/feed-archive/meteor-meteor-wrapasync

于 2014-02-04T03:21:20.613 回答
6

我能够在这个要点中找到答案。为了从 method.call 中运行异步代码,您可以使用 Futures 来强制您的函数等待。

    var fut = new Future();
    asyncfunc( data, function( err, res ){
        fut.ret( res );
    });
    return fut.wait();
于 2012-11-02T11:29:09.507 回答
0

更新:对不起,我应该更仔细地阅读这个问题。看起来这个问题也在这里被问到并得到了回答。

除了期货,要考虑的另一种模式可能是使用从异步调用返回的数据更新另一个模型,然后订阅该模型的更改。


meteor.call 文档看来(err, res),回调函数的结果参数应该包含 openSession 函数的输出。但是您没有从 openSession 函数返回任何值,因此返回值未定义。

您可以对此进行测试:

客户:

Meteor.call('foo', function(err, res) {
  console.log(res); // undefined
});

Meteor.call('bar', function(err, res) {
  console.log(res); // 'bar'
});

服务器:

Meteor.methods({
  foo: function() {
    var foo = 'foo';
  },
  bar: function() {
    var bar = 'bar';
    return bar;
  }
});
于 2012-11-02T21:10:47.230 回答