Javascript循环遍历数组无限无法工作

时间:2016-04-14 18:18:32

标签: javascript jquery

我有这个Javascript代码。

class MyLineEdit(QtGui.QLineEdit):

    def focusInEvent(self, event):
        print 'focus in event'
        # do custom stuff
        super(MyLineEdit, self).focusInEvent(event)

我这里有一个for循环,循环遍历一个充满函数的数组。在每次迭代中,检索数组中的函数并以时间间隔执行。

我想要的是在检索到最后一个函数之后,它从第一个函数开始再次循环遍历数组,并且将无限地执行此操作。

我尝试的是当计数器达到4时重置计数器但是它退出循环并继续执行,然后由于某种原因页面变得没有响应。

5 个答案:

答案 0 :(得分:3)

您需要等到最后一次执行才设置下一次超时:



var headlineStore = [
    function headline1(){
       document.write('1');
    },
    function headline2(){
       document.write('2');
    },
    function headline3(){
       document.write('3');
    },
    function headline4(){
       document.write('4');
    },
    function headline5(){
       document.write('5');
    }
]

function nextHeadline(index) {
  headlineStore[index]();
  window.setTimeout( 
    nextHeadline.bind(undefined, (index + 1) % headlineStore.length), 1000 );  
}

nextHeadline(0);




答案 1 :(得分:1)

问题是这个函数会在第一个超时触发第一个数组函数之前永远循环。您需要在超时功能中增加循环。并让它等待。

试试这个:

var headlineStore = [
    function headline1(){
       //irrelevant code
    },
    function headline2(){
       //irrelevant code
    },
    function headline3(){
       //irrelevant code
    },
    function headline4(){
       //irrelevant code
    },
    function headline5(){
       //irrelevant code
    }
]


var i = 0;

function loopForever(){
    setTimeout(function(){
        headlineStore[i]();
        i++;
        if(i == 5){
            i = 0;
        }
        loopForever();
    }, 5000  * (i + 1)); // I added the +1, else your first function fires immediately.  seemed like you didn't want that.
}

答案 2 :(得分:1)

我认为这更符合您的需求(每5秒调用1次函数)。支持使用setTimeout取决于浏览器

var timeoutHandle = undefined;

headlineStore =
[ function1
, function2
, function3
  ...
];

function showHeadline(idx) {
    headlineStore[idx](idx);
    timeoutHandle = setTimeout(showHeadline, 5000, (idx+1)%headlineStore.length);
}

showHeadline(0);

答案 3 :(得分:0)

您可以使用.queue().promise()



var headlineStore = [
  function headline1(next) {
    //irrelevant code
    console.log("headline1");
    setTimeout(next, 5000);
  },
  function headline2(next) {
    //irrelevant code
    console.log("headline2");
    setTimeout(next, 5000);
  },
  function headline3(next) {
    //irrelevant code
    console.log("headline3");
    setTimeout(next, 5000);
  },
  function headline4(next) {
    //irrelevant code
    console.log("headline4");
    setTimeout(next, 5000);
  },
  function headline5(next) {
    //irrelevant code
    console.log("headline5");
    setTimeout(next, 5000);
  }
];

(function cycle() {
  return $({}).queue("headlines", $.map(headlineStore, function(headline, i) {
      return headline
    })).dequeue("headlines")
    .promise("headlines")
    .then(cycle) // loop infinitely
}());

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
&#13;
&#13;
&#13;

答案 4 :(得分:0)

我不知道您要实现的目标,但我会尝试解释您的代码无效的原因。

JS在单线程上运行,您放在setTimeoutsetInterval中的任何函数都在event queue中排队。 此event queue中的函数仅在运行JS代码的主要文件空闲时运行。

要解释我所说的内容,请遵循以下代码

(function() {

    // A function queued to be called after 200 ms but it gets called 
    // only when the main thread has finished executing this piece of 
    // code inside the IIFE 
    setTimeout(function() { 
        console.log('Intended to be called after 200 ms delay, however called after the blocking completed');
    }, 200);

    // However the main thead is intentionally blocked here for 5 sec
    // so the queued call can only happen post this IIFE has finished 
    // execution.

    console.log('About to start 5 sec blocking');   
    var now = +new Date;
    while(+new Date - now < 5e3); // simulating 5 sec blocking
    console.log('blocking complete.');

})();

为了更好地了解队列和相关内容,我建议您观看What the heck is Event Loop

现在,回到你的问题,当你在i = 0块中设置if(i == 4)时,你无意中创建了一个无限循环。 因此,最终,您正在排队事件队列中的函数,但不会释放主线程。 因此,事件队列永远不会有机会执行。

function first() {
    console.log('hello from first function');
}

function second() {
    console.log('hello from second function');
}

function third() {
    console.log('hello from third function');
}

function fourth() {
    console.log('hello from fourth function');
}

function fifth() {
    console.log('hello from fifth function');
}

var array = [first, second, third, fourth, fifth];

for (var i = 0, len = array.length; i < len; i++) {

    if (i == 4) { i = 0;} // this causes infinite loop

    console.log('I became an infinite loop');

    // functions are added to the queue, but the main thread is stuck in an infinite loop 
    // hence cannot execute these timeouts
    (function(i) {
        setTimeout(function() {
            array[i]();
        }, 1e2*i);
    })(i);
}

因此,您需要一种方法来打开和打开函数数组。这在我看来是递归的用例。 我希望你能轻松实现。