【问题标题】:MeteorJS async code inside synchronous Meteor.methods function同步 Meteor.methods 函数中的 MeteorJS 异步代码
【发布时间】:2012-10-22 19:44:41
【问题描述】:

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

客户端.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;
        });
     }
});

【问题讨论】:

  • 我认为在客户端的流星方法中执行异步任务是不可能的。在服务器中使用 Fiber 可能是一种选择。

标签: javascript meteor


【解决方案1】:

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

    var fut = new Future();
    asyncfunc( data, function( err, res ){
        fut.ret( res );
    });
    return fut.wait();

【讨论】:

  • 我打算建议future/promise,但没有意识到它内置在Meteor中。到处都有用。
  • 你是个直 G。这是一些主教练级别的代码
  • Futures 不再是 Meteor 核心的一部分,所以这不再有效。
  • @iiz 是的。 var Future = Npm.require('fibers/future');
【解决方案2】:

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

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


meteor.call documentation 看来,您的回调函数的结果参数(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;
  }
});

【讨论】:

    【解决方案3】:

    最近版本的 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-09
      • 1970-01-01
      • 2019-01-16
      • 1970-01-01
      • 2018-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多