JS - console.log(..)输出在for循环内部的回调函数之后

时间:2018-02-09 17:18:31

标签: javascript jquery for-loop callback codepen

这是一个Freecodecamp项目(TwitchTV),它显示了几个频道数据,包括直播,onlive和all。虽然我可以有预期的结果(成功显示不同的通道数据),但我无法理解一个问题(因为它没有提供对社区的满意反馈,所以我在stackoverflow中再次发布此问题)。希望它能得到很好的回答。

这是我的代码:

var usernames = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", 
"storbeck", "habathcx", "RobotCaleb", "noobs2ninjas", "MedryBW"];
 var html_all = "";
 var html_live = "";
 var html_offline = "";


$(document).ready(function() {
 console.log("document ready");
 getChannelData();
});


// get JSON data for channels profile 
function getChannelData(i) {
  for (var i = 0; i < usernames.length; i++)
    {
      $.ajax({
         type: 'GET',
 // url: 'https://api.twitch.tv/kraken/channels/twitch/',
 url: 'https://wind-bow.glitch.me/twitch-api/channels/' + usernames[i],
 error: function() {
    console.log("error occurred when getting channel data");
 },
  success: function(data) {
   displayData(data); 
  }       
});
}
console.log("hi");
console.log(html_all);
button_click();
//   $(".data").html(html_all); // no data displayed 
}


 /* function: 
 display the channels list
 */
  function displayData(data){
    var logo = "<img src="+data.logo+" target='_blank' />";
    var name = "  <span style='font-size:20px;'>" + data.display_name +"</span>";
    var url = data.url;
    var status = data.status;
    var baseurl = "<a href=" + url + " target='_blank'>" + logo + name;
    html_all += baseurl+"</a>"+"<br>";
    $(".data").html(html_all);

    console.log('test');
    if (status != null) {
    // live list
    html_live += baseurl + "<p>" + status + "</p></a>" +"<br>";
  }
  else {
  // offline list
  html_offline += baseurl + "</a>"  +"<br>";
  }
 }


 /* function:
 add click event to buttons
 */
 function button_click(){
   $("button.button-all").on("click", function() {
   $(".data").html(html_all);
  // console.log(html_all); // test
  });
   $("button.button-live").on("click", function() {
   $(".data").html(html_live);
  });
  $("button.button-offline").on("click", function() {
  $(".data").html(html_offline);
 }); 
} 

我的问题:在定义的getChannelData()函数中,在for()循环之后,语句console.log(html_all)输出"",为空。但是全局变量html_allfor()循环之后已经更新,为什么这里是空的。但是函数button_click()按预期工作。如果您在codepen中打开我的源代码,则所有按钮都可正常工作。我不明白,如果在html_all循环后button_click()仍然为空,可以在html_all函数中访问变量for的值?回调函数$.ajax({... success: function()是否起作用?

2 个答案:

答案 0 :(得分:1)

我认为问题是getChannelData进行AJAX调用,这是异步的。如果您将console.log(html_all)置于success回调中,您应该看到自己的期望。

基本上,在加载文档时,会调用getChannelData,但AJAX请求需要一些时间才能完成;在那段时间,文档继续处理您的脚本,包括console.log(html_all)。完成了AJAX调用并设置了html_all变量,因此button_click()和其他所有内容都可以在console.log(html_all)语句完成后完成。

答案 1 :(得分:1)

默认情况下,jQuery ajax请求是异步发送的,这意味着发送请求并且代码不会等待响应,然后再继续使用其余的逻辑。当请求最终返回时,将对其进行评估以查看请求是否成功,然后运行相应的代码(例如,.success(...).fail(...)等。)

所以,这里可能发生的事情是for循环中触发的所有AJAX请求都被发送掉了,但到console.log(html_all);时,它们都没有收到响应到达了。这意味着尚未调用displayData,因此html_all的值尚未更新,并且仍包含初始化为的默认空字符串值。