Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/421.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 正在等待Meteor.startup客户端案例的多个订阅_Javascript_Meteor - Fatal编程技术网

Javascript 正在等待Meteor.startup客户端案例的多个订阅

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

我想我的Meteor客户端启动代码遇到了竞争条件

简要背景

我正在使用Meteor作为HTML5游戏大厅界面。当用户刷新页面或稍后返回菜单时,我希望客户端为该用户查找任何正在进行的游戏。但是,在启动期间,我无法访问任何集合

下面是我的
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()
函数,您应该能够对其进行测试,而不是使用单独的会话变量,但出于某些原因,我发现会话方式更可靠: