循环处理按顺序进行 [英] For loop proceeding out of order

查看:139
本文介绍了循环处理按顺序进行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我正在处理的代码可以在这里看到:

在这个新的,请告诉我,如果我留下信息或类似的东西。 http://codepen.io/hutchisonk/pen/mVyBde ,我也粘贴了相关的下面的JavaScript。

我很难理解为什么这个代码的行为是这样的。快速提纲 - 我在顶部定义了一些变量,提供了一个函数来获取我需要的数据,并将其构建到一个很小的列表中。这似乎按计划正常工作。

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

两个主要问题:
$ b $ 1)每个名字前面的数字是我for循环中的i。为什么这个我不是从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 =;

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);
$ b $ // $ success
}); // $ ajax
} // getstreamingdata函数


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

//与上面的循环相同,但是使用forEach。这产生了相同的结果。
/ *
var i = 0;
friends.forEach(function(friend){
getStreamingData(friend,i);
i ++;
});
* /

var a = 4; //测试控制台输出
console.log(a);
console.log(为什么在getStreamingData函数的控制台输出之前显示?);
console.log(但它显示在console.log(i)和console.lg(friends [i])之后输出?所以本节介绍了for循环上面的);
console.log(为什么for循环出故障并重复自己?);

)); // doc ready


解决方案

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



函数 getStreamingData 是我在说。



相关:在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);

触摸原型并不是一个好习惯像这样。但只是给你一个想法你可以做到这一点...
在代码之后,你可以循环数组异步。当你完成一个元素时,请调用 next 。

  var array = [1,2,3,4] 
array.forEachAsync(function(item,next){
//做一些异步任务
console.log(item +started);
setTimeout(function(){
console.log(item +done);
next();
},1000);
},function ){
console.log(All done!);
});


new at this, please tell me if I'm leaving information out or anything like that.

The code I'm working on can be seen here: http://codepen.io/hutchisonk/pen/mVyBde and I have also pasted the relevant section of javascript below.

I'm having trouble understanding why this code is behaving as it is. Quick outline - I have defined a few variables at the top, made a function that fetches the data I need and builds it into a pretty little list. This seems to be working as planned.

With the function outlined, I then loop through each "friend" in the "friends" array, calling the function once each time. I have numbered the friends on the output to help clarify what is going on. I have tried this a number of ways, including with the "for loop" syntax that's currently implemented, as well as the "forEach" syntax that's commented out.

Two main questions:

1) The number in front of each name is the "i" in my for loop. Why is this "i" not going in order from 0 to 10? How do I get it to do so? It appears to be in a different order every time the code is run. And, it repeats the numbers it has looped through previously on each new iteration. I would like to understand why this is happening.

2) The code seems to be running out of order. The unexpected behavior can be seen in the console.log - the for loop outputs the first two lines of console.log on a loop, then jumps out and console.logs the test variable "a" and the other text below the for loop, and then jumps back into the for loop and console.logs the output from the function. I'm looking at the console in google chrome and I did read that there can be timing inconsistancies with regard to the console, but I don't understand how the loop is being split in half - the first two lines, and then the function call being logged after the later code.

What is the best way to iterate through an array? Any insights on how to call a function within a loop correctly or resources you can provide are much appreciated.

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

解决方案

You are doing an asynchronous task in your loop. You should not expect those async tasks finish in the order that they have started.

The function getStreamingData is the one that I'm talking about.

Related: Asynchronous for cycle in JavaScript

This is one snippet that I wrote long time ago and I'm still using it in small projects. However there are many libraries out there which do the same plus many more.

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);
}

It is not a good practice to touch the prototype like this. But just to give you an idea how you can do this ... After that code, you can loop over arrays asynchronously. When you are done with one element, call 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!");
});

这篇关于循环处理按顺序进行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆