Meteor使用meteorhacks:npm包异步运行一个方法

时间:2016-01-02 23:19:59

标签: javascript node.js meteor steam

我正在尝试使用Steam社区(steamcommunity)npm包以及meteorhacks:npm Meteor包来检索用户的广告资源。我的代码如下:

LIB / methods.js:

Meteor.methods({
  getSteamInventory: function(steamId) {
    // Check arguments for validity
    check(steamId, String);

    // Require Steam Community module
    var SteamCommunity = Meteor.npmRequire('steamcommunity');
    var community = new SteamCommunity();

    // Get the inventory (730 = CSGO App ID, 2 = Valve Inventory Context)
    var inventory = Async.runSync(function(done) {
      community.getUserInventory(steamId, 730, 2, true, function(error, inventory, currency) {
        done(error, inventory);
      });
    });

    if (inventory.error) {
      throw new Meteor.Error('steam-error', inventory.error);
    } else {
      return inventory.results;
    }
  }
});

客户端/视图/ inventory.js:

Template.Trade.helpers({
  inventory: function() {
    if (Meteor.user() && !Meteor.loggingIn()) {
      var inventory;
      Meteor.call('getSteamInventory', Meteor.user().services.steam.id, function(error, result) {
        if (!error) {
          inventory = result;
        }
      });

      return inventory;
    }
  }
});

尝试访问呼叫结果时,客户端或控制台上不显示任何内容。

我可以在console.log(inventory)函数的回调中添加community.getUserInventory,并在服务器上接收结果。

相关文档:

2 个答案:

答案 0 :(得分:2)

您必须在inventory帮助程序中使用被动数据源。否则,Meteor不知道何时重新运行它。您可以在模板中创建ReactiveVar

Template.Trade.onCreated(function() {
  this.inventory = new ReactiveVar;
});

在帮助程序中,通过获取其值来建立反应依赖:

Template.Trade.helpers({
  inventory() {
    return Template.instance().inventory.get();
  }
});

设置值发生在Meteor.call回调中。顺便说一下,你不应该在助手里面调用这个方法。有关详细信息,请参阅David Weldon's blog post on common mistakes过度工作的助手部分)。

Meteor.call('getSteamInventory', …, function(error, result) {
  if (! error) {
    // Set the `template` variable in the closure of this handler function.
    template.inventory.set(result);
  }
});

答案 1 :(得分:2)

我认为这里的问题是您在 getSteamInventory Meteor方法中调用异步函数,因此它总是会尝试在实际获得结果之前返回结果strong> community.getUserInventory 调用。幸运的是,对于这种情况,Meteor有WrapAsync,所以你的方法就变成了:

Meteor.methods({
  getSteamInventory: function(steamId) {
    // Check arguments for validity
    check(steamId, String);

    var community = new SteamCommunity();
    var loadInventorySync = Meteor.wrapAsync(community.getUserInventory, community);

    //pass in variables to getUserInventory
    return loadInventorySync(steamId,730,2, false);
  }
});

注意:我将SteamCommunity = Npm.require('SteamCommunity')移动到了全局变量,因此我不必在每次方法调用时都声明它。

然后您可以在客户端上调用此方法,就像您已经按照Chris概述的方式完成的那样。