【问题标题】:Meteor running a Method asynchronously, using meteorhacks:npm packageMeteor 异步运行方法,使用 meteorhacks:npm 包
【发布时间】:2016-01-02 23:19:58
【问题描述】:

我正在尝试使用 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;
    }
  }
});

client/views/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;
    }
  }
});

当尝试访问调用结果时,客户端或控制台上没有显示任何内容。

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

相关文档:

【问题讨论】:

    标签: javascript node.js meteor steam


    【解决方案1】:

    您必须在 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 mistakesOverworked Helpers 部分)。

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

    【讨论】:

    • 我已经这样做了,并选择在onCreated 回调中执行Meteor.call,但是我仍然没有在客户端上得到任何东西。正如 David Weldon 的帖子中所建议的那样,我已按照 this question 的答案进行操作。
    【解决方案2】:

    我认为这里的问题是您在 getSteamInventory Meteor 方法中调用了一个异步函数,因此它总是会在您真正从 获得结果之前尝试返回结果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 概述的方式完成的那样。

    【讨论】:

    • 那个小的Meteor.wrapAsync 超过meteorhacks:npm 的函数版本,加上@chrisklaussner 的其他答案:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-15
    • 1970-01-01
    • 1970-01-01
    • 2016-06-07
    • 1970-01-01
    • 2016-12-02
    相关资源
    最近更新 更多