Meteor 运行 异步方法,使用 meteorhacks:npm 包
Meteor running a Method asynchronously, using meteorhacks:npm package
我正在尝试使用 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)
并在服务器上接收结果。
相关文档:
您必须在 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);
}
});
我认为这里的问题是你在你的 getSteamInventory Meteor 方法中调用了一个异步函数,因此它总是会在你之前尝试 return 结果实际上有 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')
移动到全局变量,这样我就不必在每次方法调用时都声明它。
然后您可以按照克里斯概述的方式在客户端调用此方法。
我正在尝试使用 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)
并在服务器上接收结果。
相关文档:
您必须在 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);
}
});
我认为这里的问题是你在你的 getSteamInventory Meteor 方法中调用了一个异步函数,因此它总是会在你之前尝试 return 结果实际上有 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')
移动到全局变量,这样我就不必在每次方法调用时都声明它。
然后您可以按照克里斯概述的方式在客户端调用此方法。