2015-12-09 3 views
0

Новое на этом, пожалуйста, скажите мне, оставляю ли я информацию или что-то в этом роде.Для цикла, выходящего из строя

Код, над которым я работаю, можно посмотреть здесь: http://codepen.io/hutchisonk/pen/mVyBde, и я также вставил соответствующий раздел javascript ниже.

У меня возникли проблемы с пониманием, почему этот код ведет себя как есть. Краткое описание. Я определил несколько переменных наверху, создал функцию, которая извлекает нужные мне данные и создает ее в довольно маленький список. Кажется, это работает так, как планировалось.

С помощью описанной функции я затем прокручиваю каждый «друг» в массиве «друзей», вызывая функцию один раз каждый раз. Я пронумеровал друзей на выходе, чтобы помочь прояснить, что происходит. Я пробовал это несколькими способами, в том числе с синтаксисом «for loop», который в настоящее время реализован, а также синтаксисом «forEach», который закомментирован.

Две основные вопросы:

1) Число перед каждым именем является «я» в мой цикл. Почему это «я» не идет в порядке от 0 до 10? Как мне это сделать? Кажется, что он находится в другом порядке каждый раз, когда выполняется код. И он повторяет числа, которые он зацикливал ранее на каждой новой итерации. Я хотел бы понять, почему это происходит.

2) Код, похоже, исчерпан. Неожиданное поведение можно увидеть в console.log - цикл for выдает первые две строки console.log в цикле, затем выпрыгивает, а console.logs - тестовую переменную «a», а другой текст под циклом for, а затем возвращается обратно в цикл for, а console.log выводит из функции. Я смотрю консоль в google chrome, и я прочитал, что могут быть временные несоответствия относительно консоли, но я не понимаю, как цикл разбивается пополам - первые две строки, а затем функция вызов записывается после более позднего кода.

Каков наилучший способ перебора массива? Любое понимание того, как правильно вызывать функцию в цикле или ресурсы, которые вы можете предоставить, очень ценится.

$("document").ready(function(){ 

    var friends = ["lainzero", "freecodecamp", "storbeck", "terakilobyte", "habathcx","RobotCaleb","thomasballinger","noobs2ninjas","beohoff", "dtphase", "MedryBW"]; 
    var html = ""; 
    var url = ""; 

    function getStreamingData(eachfriend, number) { 
    url = "https://api.twitch.tv/kraken/streams/"+eachfriend; 

    $.ajax({ 
    dataType: "jsonp", 
    url: url, 
    success: function(result) { 
     console.log(result+", "+result.stream); 

    if(result.stream !== null) { 
     html+= "<li class='streaming'><a href='twitch.tv/"+eachfriend+"'>"+number+": "+eachfriend; 
     html +="<i class='fa fa-play-circle style='font-size:20px;color:green;''></i>"; 
    } else if (result.stream === null) { 
     html+= "<li class='not_streaming'><a href='twitch.tv/"+eachfriend+"'>"+number+": "+eachfriend; 
     html +="<i class='fa fa-stop-circle' style='font-size:20px;color:red;'></i>"; 
    } 
    html +="</a></li>"; 
    $("#all ul").append(html); 

    }//success 
    });//$ajax 
}//getstreamingdata function 


for (var i=0;i<friends.length;i++) { 
    console.log(i); 
    console.log(friends[i]); 
    getStreamingData(friends[i], i); 
} 

//Same as for loop above, but using forEach. This produces the same results. 
/* 
var i=0; 
friends.forEach(function(friend) { 
    getStreamingData(friend, i); 
    i++; 
});  
    */ 

    var a = 4;//testing console output 
    console.log(a); 
    console.log("why is this showing up before the getStreamingData function's console output?"); 
    console.log("but it's showing up after the console.log(i) and console.lg(friends[i]) output? So this section is interupting the for loop above"); 
    console.log(" and why is the for loop out of order and repeating itself?"); 

});//doc ready 

ответ

0

Вы выполняете асинхронную задачу в своем цикле. Вы не должны ожидать завершения этих задач async в том порядке, в котором они были запущены.

Функция getStreamingData - это та, о которой я говорю.

Похожие: Asynchronous for cycle in JavaScript

Это один фрагмент кода, который я написал давно, и я до сих пор используют его в небольших проектах. Однако есть много библиотек, которые делают то же самое плюс еще много.

Array.prototype.forEachAsync = function (cb, end) { 
    var _this = this; 
    setTimeout(function() { 
     var index = 0; 
     var next = function() { 
      if (this.burned) return; 
      this.burned = true; 
      index++; 
      if (index >= _this.length) { 
       if (end) end(); 
       return; 
      } 
      cb(_this[index], next.bind({})); 
     } 
     if (_this.length == 0) { 
      if (end) end(); 
     }else { 
      cb(_this[0], next.bind({})); 
     } 
    }, 0); 
} 

Это не очень хорошая практика, чтобы коснуться prototype как это. Но просто для того, чтобы дать вам представление о том, как вы можете это сделать ... После этого кода вы можете асинхронно перебирать массивы. Когда вы закончите с одним элементом, вызовите next.

var array = [1, 2, 3, 4] 
array.forEachAsync(function (item, next) { 
    // do some async task 
    console.log(item + " started"); 
    setTimeout(function() { 
     console.log(item + " done"); 
     next(); 
    }, 1000); 
}, function() { 
    console.log("All done!"); 
}); 
Смежные вопросы