【问题标题】:How to get an async data in a function with Meteor如何使用 Meteor 在函数中获取异步数据
【发布时间】:2016-06-15 16:40:13
【问题描述】:

我是 Meteor 的新手,我正在尝试从 Heroku API 获取异步数据。

服务器端代码:

heroku = Meteor.require("heroku");

Meteor.methods({
    'getHeroku': function getHeroku(app){
        client = new heroku.Heroku({key: "xxxxxx"});
        client.get_app(app, function (error, result) {
            return result;
        });
    }
});

客户端代码:

Template.herokuDashboard.helpers({
    appInfo: function() {
        Meteor.call('getHeroku', "meathook-api", function (error, result) {
            console.warn(result);
        } );
    }
});

Heroku 需要一段时间来回答,所以答案是 undefined

那么捕获异步结果的最佳方法是什么?

谢谢。

【问题讨论】:

标签: javascript meteor


【解决方案1】:

一般解决方案:

客户端:

    if (Meteor.isClient) {
        Template.herokuDashboard.helpers({
            appInfo: function() {
                return Session.get("herokuDashboard_appInfo");
            }
        });
        Template.herokuDashboard.created = function(){
            Meteor.call('getData', function (error, result) {
                Session.set("herokuDashboard_appInfo",result);
            } );
        }
    }

没有办法直接从 Meteor.call 返回结果。 但是至少有 2 个解决方案(@akshat 和 @Hubert OG): How to use Meteor methods inside of a template helper

服务器端(Meteor._wrapAsync):

使用 Meteor._wrapAsync :

if (Meteor.isServer) {
  var asyncFunc = function(callback){
      setTimeout(function(){
          // callback(error, result);
          // success :
          callback(null,"result");
          // failure:
          // callback(new Error("error"));
      },2000)
  }
  var syncFunc = Meteor._wrapAsync(asyncFunc);
  Meteor.methods({
      'getData': function(){
          var result;
          try{
               result = syncFunc();
          }catch(e){
              console.log("getData method returned error : " + e);
          }finally{
              return result;
          }

      }
  });
}

正确使用 Future 库:

if (Meteor.isServer) {
    Future = Npm.require('fibers/future');

    Meteor.methods({
        'getData': function() {
            var fut = new Future();
            setTimeout(
                Meteor.bindEnvironment(
                    function() {
                        fut.return("test");
                    },
                    function(exception) {
                        console.log("Exception : ", exception);
                        fut.throw(new Error("Async function throw exception"));
                    }
                ),
                1000
            )
            return fut.wait();
        }
    });
}

不推荐使用 Future 库WITHOUT Meteor.bindEnvironment不推荐,请参阅:

还有第三种方法使用Async utilities

【讨论】:

  • 谢谢 Kuba,但我已经尝试过了。也许我做错了,因为它给了我这个错误:cl.ly/image/0A2M2x143k0C 完整的服务器端代码:pastebin.com/RKQH0tzF
  • 我将fut.ret 更改为fut.return。那应该可以。
  • 同样的错误 :( TypeError: Object #<Future> has no method 'return'TypeError: Object #<Future> has no method 'wait' 我认为这是因为它已被弃用 (github.com/meteor/meteor/issues/1311#issuecomment-22686373) 但我找不到替代方法
  • 这样做:fut["return"](results)
  • @KubaWyrobek 理想情况下,您根本不应该直接使用 Fibers。因为在 Fibers 上附加了一个额外的动态环境,如果您手动创建新的 Fiber,您不会复制它。 Meteor.bindEnvironment 既创建了一个纤程,又为您附加了正确的环境。如果您不这样做,您可能会遇到错误,例如在 Meteor.call 中没有请求信息或登录信息
猜你喜欢
  • 1970-01-01
  • 2022-11-07
  • 2019-04-25
  • 2015-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多