【问题标题】:Can't access a global array inside $.getJSON function无法访问 $.getJSON 函数中的全局数组
【发布时间】:2016-08-23 11:51:58
【问题描述】:

我正在为 Twitch TV 创建一个“查看器”,它可以显示电视频道是在线、离线还是不存在。我正在使用用于 Twitch TV 的 API。我已将频道名称保存在数组中,但是当我尝试将数组项附加到 HTML 元素时,它显示“未定义”。该数组是一个全局变量。

我的代码是in this fiddle

HTML:

<div class="container-fluid">

<div class="row row-centered">

<div class="col-md-4"></div>  
<!-- This is a div containing divs for each channel --> 
<div class="col-md-4 col-centered" id="displayHere">


</div>
<!-- The container div end here -->
<div class="col-md-4"></div>  

</div>  

</div>

我的 Javascript:

$(document).ready(function(){
streamsArr=  ["ESl_SC2","OgamingSC2","cretetion","freecodecamp","storbeck","habathcx","RobotCaleb","noobs2ninjas","brunofin","comster404"];

 for(var count=0;count<streamsArr.length;count++){
 $.getJSON("https://api.twitch.tv/kraken/streams/"+streamsArr[count]+"?callback=?",function(data){

  if(JSON.stringify(data.stream)=="null")
   {
       $("#displayHere").append("<div style=\"padding:1%;\"><span style=\"font-size:1.3em;\"> "+streamsArr[count]+"</span><span style=\"color:red;\">OFFLINE</span></div>");//shows 'undefined'
    }
  else if(data.hasOwnProperty("error"))
    {
      $("#displayHere").append("<div style=\"padding:1%;\"><span style=\"font-size:1.3em;\"> "+streamsArr[count]+"</span><span style=\"color:red;\">UNAVAILABLE</span></div>");//shows 'undefined'
    }
  else{
  $("#displayHere").append("<div style=\"padding:1%;\"><span style=\"font-size:1.3em;\"> "+JSON.stringify(data.stream.channel.display_name)+"</span>"+JSON.stringify(data.stream.game)+"</div>");
  }
}); 
 } 
});

谁能告诉我错在哪里?谢谢。

【问题讨论】:

标签: javascript jquery html arrays api


【解决方案1】:

您已经为变量count 创建了一个闭包,因为 JavaScript 具有函数作用域,这就是为什么您的 count 变量的值始终为 10。在 ES6 中,您可以在 for 中使用 let 而不是 var循环,所以count 将是块作用域。

【讨论】:

  • 谢谢!这适用于 Firefox 和 Chrome,但不适用于 Microsoft Edge 和 Internet Explorer。
【解决方案2】:

$.getJSON 方法是异步的,因此For 循环可能在当前请求返回结果之前完成。所以变量count的值变成了10。

这是一个有效的小提琴 https://jsfiddle.net/bkw5dLac/1/

$(document).ready(function(){
streamsArr=  ["ESl_SC2","OgamingSC2","cretetion","freecodecamp","storbeck","habathcx","RobotCaleb","noobs2ninjas","brunofin","comster404"];

 for(var count=0;count<streamsArr.length;count++){ 
 getJSON(streamsArr[count]);
 } 
});

function getJSON(arr){
$.getJSON("https://api.twitch.tv/kraken/streams/"+arr+"?callback=?",function(data){
  if(JSON.stringify(data.stream)=="null")
   {
       $("#displayHere").append("<div style=\"padding:1%;\"><span style=\"font-size:1.3em;\"> "+arr+"</span><span style=\"color:red;\">OFFLINE</span></div>");//shows 'undefined'
    }
  else if(data.hasOwnProperty("error"))
    {
      $("#displayHere").append("<div style=\"padding:1%;\"><span style=\"font-size:1.3em;\"> "+arr+"</span><span style=\"color:red;\">UNAVAILABLE</span></div>");//shows 'undefined'
    }
  else{
  $("#displayHere").append("<div style=\"padding:1%;\"><span style=\"font-size:1.3em;\"> "+JSON.stringify(data.stream.channel.display_name)+"</span>"+JSON.stringify(data.stream.game)+"</div>");
  }
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container-fluid">

<div class="row row-centered">

<div class="col-md-4"></div>  
<!-- This is a div containing divs for each channel --> 
<div class="col-md-4 col-centered" id="displayHere">


</div>
<!-- The container div end here -->
<div class="col-md-4"></div>  

</div>  

</div>

为什么 OP 的代码不能按预期工作

1) 变量count$.getJSON匿名回调函数的全局变量

2) $.getJSON 是异步的。所以只有get请求成功后才会触发匿名回调函数。

3) 当匿名回调执行时,count 的值将在 for 循环中被修改。很多情况下变成10。因为for循环在触发回调之前就完成了执行

为什么我的小提琴奏效了

1) 我已将streamArrcount 的值传递给局部变量arr

2) 因为arr 是函数getJSON 的局部变量,所以它的值不会在for 循环中被修改。所以匿名回调函数按预期工作。

【讨论】:

  • 谢谢!那工作得很好。但是,您能否更清楚地说明为什么您的代码有效而我的代码无效?您和我的代码之间的唯一区别是我直接将 getJSON 嵌套在 for 循环中,而您在 for 循环中包含了一个回调。
【解决方案3】:

让我们先尝试清理一下$.getJSON 函数:

var twitchAPI = "https://api.twitch.tv/kraken/streams/"+streamsArr[count]+"?callback=?"

然后将成功回调封装在一个绑定了索引的闭包中:

$.getJSON(twitchAPI, function(count) {
    return function(data) {
        if (JSON.stringify(data.stream) == "null") {
            $("#displayHere").append("<div style=\"padding:1%;\"><span style=\"font-size:1.3em;\"> " + streamsArr[count] + "</span><span style=\"color:red;\">OFFLINE</span></div>");
        } else if (data.hasOwnProperty("error")) {
            $("#displayHere").append("<div style=\"padding:1%;\"><span style=\"font-size:1.3em;\"> " + streamsArr[count] + "</span><span style=\"color:red;\">UNAVAILABLE</span></div>");
        } else {
            $("#displayHere").append("<div style=\"padding:1%;\"><span style=\"font-size:1.3em;\"> " + JSON.stringify(data.stream.channel.display_name) + "</span>" + JSON.stringify(data.stream.game) + "</div>");
        }
    }
}(count));

【讨论】:

  • 感谢您的帮助。这段代码是否有效,因为您已将“count”变量作为参数传递,而我没有?此外,令人困惑的是,当 JSON 对象“数据”未作为 $.getJSON(url,function(data){}) 之类的参数传递时,getJSON 函数是如何工作的;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-06
  • 1970-01-01
  • 2011-07-23
  • 2013-01-11
  • 1970-01-01
  • 2011-09-05
  • 2020-01-11
相关资源
最近更新 更多