对于循环不按顺序进行循环

时间:2015-12-09 17:12:09

标签: javascript loops for-loop foreach

这是新的,请告诉我是否要留下信息或类似的东西。

我可以在此处看到我正在处理的代码:http://codepen.io/hutchisonk/pen/mVyBde我也粘贴了以下javascript的相关部分。

我无法理解为什么这段代码会按原样运行。快速概述 - 我在顶部定义了一些变量,创建了一个函数来获取我需要的数据并将其构建到一个非常小的列表中。这似乎按计划进行。

随着概述的功能,我然后遍历每个"朋友"在"朋友"数组,每次调用一次函数。我已经对输出中的朋友进行了编号,以帮助澄清正在发生的事情。我已经尝试了很多方法,包括使用" for循环"当前实现的语法,以及" forEach"已被注释掉的语法。

两个主要问题:

1)每个名字前面的数字是" i"在我的for循环中。为什么这是"我"不是从0到10的顺序?我怎么做到这一点?每次运行代码时,它看起来都是不同的顺序。而且,它重复了之前在每次新迭代中循环的数字。我想了解为什么会这样。

2)代码似乎无法正常运行。在console.log中可以看到意外的行为 - for循环在循环中输出console.log的前两行,然后跳出并调试console.logs测试变量" a"和for循环下面的另一个文本,然后跳回到for循环和console.logs函数的输出。我在谷歌浏览器中查看控制台,我确实读到控制台可能存在时间差异,但我不明白循环如何分成两半 - 前两行,然后在后面的代码之后记录函数调用。

迭代数组的最佳方法是什么?有关如何正确调用循环中的函数或您可以提供的资源的任何见解都非常感谢。

$("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

1 个答案:

答案 0 :(得分:0)

您正在循环中执行异步任务。您不应该期望这些异步任务按照它们已经开始的顺序完成。

函数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!");
});