Javascript 正在等待Meteor.startup客户端案例的多个订阅
我想我的Meteor客户端启动代码遇到了竞争条件 简要背景 我正在使用Meteor作为HTML5游戏大厅界面。当用户刷新页面或稍后返回菜单时,我希望客户端为该用户查找任何正在进行的游戏。但是,在启动期间,我无法访问任何集合 下面是我的Javascript 正在等待Meteor.startup客户端案例的多个订阅,javascript,meteor,Javascript,Meteor,我想我的Meteor客户端启动代码遇到了竞争条件 简要背景 我正在使用Meteor作为HTML5游戏大厅界面。当用户刷新页面或稍后返回菜单时,我希望客户端为该用户查找任何正在进行的游戏。但是,在启动期间,我无法访问任何集合 下面是我的client.js文件顶部的摘录 Meteor.subscribe("players"); //Meteor.Collection("players" references Meteor.users via user_id Meteor.subscribe("gam
client.js
文件顶部的摘录
Meteor.subscribe("players"); //Meteor.Collection("players" references Meteor.users via user_id
Meteor.subscribe("games"); // each player has a game_id, linked to Meteor.Collection("games"
if (Meteor.isClient) {
Meteor.startup(function () {
//find the player from the user_id, find game from player.game_id
var current_user_id = Meteor.userId();
var playerFromUser = Players.findOne({"user_id":current_user_id});
if(typeof playerFromUser !== 'undefined'){
var getGame = Games.findOne(playerFromUser.game_id);
if(typeof getGame !== 'undefined'){
alert('game found!'); //is not reached
}else{
alert('game not found'); //is not reached
}
}else{
alert('player not found'); //*********** IS reached. Why? ***********
}
});
}
但是,在javascript控制台中,我可以运行Players.findOne({“user_id”:Meteor.userId());
并且它可以返回一个有效的播放器。我的集合中的竞争条件是什么
编辑1:
深入查看库,我发现我错误地认为服务器的数据将立即可用。订阅实际上需要一段时间才能处理,这就是为什么在客户端启动时它们不可用的原因。我正在更新我的问题以表达这些新信息
更新的问题
由于我依赖多个订阅为用户(包括玩家和游戏)找到一个游戏,有没有一种流星式的方法可以同时等待这两个呢?仅仅为了获得一个可能正在进行的游戏而单独订阅似乎是错误的。需要任何服务器调用也是错误的
我觉得应该能够找到游戏,我需要从检索到的球员和游戏,一旦他们进来,而不是麻烦与任何更多的电话服务器
一旦我找到了自己的解决方案,我会在这里发布。好的,这里是我所拥有的似乎有效的东西: 基本上,我在会话中添加了在两个订阅的就绪回调上设置的标志。然后,
Deps.autorun
函数侦听要设置的会话值,并执行其余操作
if (Meteor.isClient) {
Meteor.subscribe("players", function(){
console.log("players_loaded ");
Session.set('players_loaded', true);
}); //linked to Meteor.users with user_id
Meteor.subscribe("games", function(){
console.log("games_loaded ");
Session.set('games_loaded', true);
}); // each player has a game_id
Deps.autorun(function(){
var gamesLoaded = Session.get('games_loaded');
var playersLoaded = Session.get('players_loaded');
if(gamesLoaded && playersLoaded &&
(typeof Players !== 'undefined') && (typeof Games !== 'undefined') ) {
console.log("both loaded! ");
//find the player from the user_id, find game from player.game_id
var playerFromUser = Players.findOne({"user_id":Meteor.userId()});
if(typeof playerFromUser !== 'undefined'){
var getGame = Games.findOne(playerFromUser.game_id);
if(typeof getGame !== 'undefined'){
console.log("game found : " + getGame);
//Do stuff with the game now that we have it
}else{
console.log("no game :(");
}
}else{
console.log("no player :(");
}
}
});
Meteor.startup(function () {
Session.set("title", "whatever else");
Session.set("games_loaded", false);
Session.set("players_loaded", false);
console.log("DOM loaded");
});
}
这里希望我能帮助一些人。是的,这就是我在我们的应用程序中所做的。订阅本身也有一个
ready()
函数,您应该能够对其进行测试,而不是使用单独的会话变量,但出于某些原因,我发现会话方式更可靠: