为什么阵列会失去它的价值?

时间:2015-09-28 20:09:56

标签: javascript jquery api

我正在尝试使用twitch api构建一个列表,当用户想要查看谁是流媒体以及谁不是时,更新列表。例如,当我按下离线按钮时,列表应该只包含“stream”值为null的用户。这是我的HTML:

<div class="container-fluid">
  <div id="menu">
    <ul class="menubar">
      <li><a id="all" href="#">All</a></li>
      <li><a id="online" href="#">Online</a></li>
      <li><a id="offline" href="#">Offline</a></li>
    </ul>
    <div id="users">
      <ul class="members">
      </ul>
    </div>
  </div>
</div>

这是我的javascript(已导入jQuery):

var users = ["MedryBW", "freecodecamp", "storbeck", "terakilobyte", "habathcx","RobotCaleb","thomasballinger","noobs2ninjas","beohoff"];

var listOffline = [];

$(document).ready(function(){
  $.each(users, function(i , val){
      $('.members').append("<li>" + val + "</li>"); 
  }); 

  $('#offline').on('click', function(){
     $.each(users, function(i , val){
       $.getJSON("https://api.twitch.tv/kraken/streams/" + val , function(data){
          if(data['stream'] == null) {
            listOffline.push(val);
          }
       });
     });
    $('.members li').remove();
    $.each(listOffline, function(i , val) {
      $('.members').append("<li>" + val + "</li>");
    });

  });

});

为什么'listOffline'数组会丢失在$('#offline')。on('click')函数的第一个.each块结尾处推送到它的值?任何帮助解决这个问题将非常感谢

3 个答案:

答案 0 :(得分:1)

问题是您在填充列表之前尝试附加列表。因为$ .getJSON是一个异步函数。另请注意,您需要在循环用户之前调用remove函数清空列表。

您应该在成功回调函数

中附加列表
 $('#offline').on('click', function(){
 $('.members li').remove();
     $.each(users, function(i , val){
       $.getJSON("https://api.twitch.tv/kraken/streams/" + val , function(data){
          if(data['stream'] == null) {
            listOffline.push(val);
             $('.members').append("<li>" + val + "</li>");
          }
       });
     });

答案 1 :(得分:1)

我的猜测是$ .getJson是异步的,这意味着在从服务器返回所有结果之前到达并执行了最后一个循环,因此您正在处理部分列表。

要验证这一点,请添加以下打印输出:

在处理$ .getJson响应的块中,在条件之前:

console.log('user ', val, ' retrieved);

就在你最后一次循环之后:

console.log('offline list processed');

您可能会在处理完列表后看到用户被检索(+处理并推送)。

如果是这种情况,您可以执行以下操作之一:

  • 使用promises并仅在完成后执行最后一个循环
  • 甚至更简单,当你得到一个结果,而不是把它推入一个数组时,只需这样做:

     $('.members').append("<li>" + val + "</li>");
    

答案 2 :(得分:0)

getJSON调用是异步的,因此回调中的代码将在下一个.each之后执行。尝试移动回调中的最后.each

$('#offline').on('click', function(){
   $('.members li').remove();
   $.each(users, function(i , val){
     $.getJSON("https://api.twitch.tv/kraken/streams/" + val).done(function(data){
       if (data['stream'] == null) {
         listOffline.push(val);
         $('.members').append("<li>" + val + "</li>");
       }
   });
 });

您还可以使用延迟.done来保持一点清洁。