为什么setInterval一次记录所有数据而不是每次都等待指定的间隔?

时间:2016-08-15 02:44:26

标签: javascript setinterval

我想使用for循环以每秒两秒的间隔打印一些数字。所有这些片段都需要外部循环,因为我需要它进行其他一些操作,所以请不要说不需要两个循环。

以下代码段等待约2秒钟,然后一次打印61次。

for(var i=0;i<1;i++) { 
    for(var j=1;j<51;j++) {
        window.setInterval(function(){
            console.log(10*i + j);
        }, 2000);
    }  
}

我认为它会打印1 - 等待2秒 - 打印2 - 等待2秒 - 依此类推。我以为我要求浏览器在内循环的每次迭代后停止两秒钟,然后打印数字。此外,我认为打印将在外循环的一次迭代后停止,但它没有,并且控制台保持打印61.还有一件事,为什么打印61?

编辑:在zerkms的评论之后,我现在有以下代码:

for(var i=0;i<1;i++) { 
    for(var j=1;j<51;j++) {
        window.setTimeout(function(){
            console.log(10*i + j);
        }, 2000*j);
    }  
}

以2秒的间隔打印50行,但每次打印61行。如何打印所有数字?

1 个答案:

答案 0 :(得分:1)

  

我以为我要求浏览器在内循环的每次迭代后停止两秒钟,然后打印数字。

你只是误解了setInterval的性质。当你致电setInterval时,你会说:

  

浏览器,我将为您提供一个功能,我希望您每隔两秒运行一次该功能,直到我告诉您停止。

做一个你希望做的事的正确方法是:

var i = 0;
var j = 1;
var interval = window.setInterval(function(){
    console.log(i, j);
    j++;
    if(j > 50) {
        j = 0;
        i++;
        if(i > 4) {
            window.clearInterval(interval);
        }
    }
}, 2000);

您会注意到您不需要任何循环,因为setInterval已经为您重复了您的功能。如果没有循环,则需要将递增逻辑(i = 0i++等)移动到正常语句中。然后,一旦您想要停止,您必须通过clearInterval告诉浏览器停止。

这很难理解,所以根据你实际想要完成的事情,可能会有更好的方法。例如,如果你试图迭代几个数组,交叉连接时,你可以先flatten your arrays out,不需要你的一个迭代器。或者您可以使用像{RxJS这样的库zipinterval timer所需的值用于{{3}}。

var everyTwoSeconds = Rx.Observable.interval(2000);
var firstSetOfThings = Rx.Observable.from(['one', 'two', 'three']);
var secondSetOfThings = Rx.Observable.range(1, 50);
var allTheThings = firstSetOfThings.flatMap(secondSetOfThings, function(x, y) {
    return "first: " + x + ", second: " + y;
});
everyTwoSeconds.zip(allTheThings, function(i, thing) { console.log(thing); });