meteor运行一个方法asynchronous,使用meteorhacks:NPM包

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

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

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

相关文件:

  • https://github.com/meteorhacks/npm
  • https://github.com/DoctorMcKay/node-steamcommunity/wiki/CSteamUser#getinventoryappid-contextid-tradableonly-callback

您必须在inventory帮助器中使用react native数据源。 否则,meteor不知道什么时候重新运行它。 你可以在模板中创build一个ReactiveVar

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

在助手中,你通过获得它的值来build立被动依赖关系:

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

设置值在Meteor.callcallback中发生。 顺便说一句,你不应该在helper里面调用方法。 有关详细信息,请参阅David Weldon关于常见错误的博客文章 ( Overworked Helpers章节)。

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

我认为这里的问题是你在你的getSteamInventory Meteor方法中调用一个asynchronous函数,因此它总是会尝试返回结果,然后实际上从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')移到了一个全局SteamCommunity = Npm.require('SteamCommunity') ,这样我就不必每次调用方法都要声明它。

然后你可以在客户端调用这个方法,就像你已经按照克里斯的方法所做的那样。