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

Javascript 为什么setInterval一次记录所有数据,而不是每次等待指定的时间间隔?,javascript,setinterval,Javascript,Setinterval,我想使用for循环以每两秒的间隔打印一些数字。在所有这些代码段中都需要外循环,因为我需要它进行其他操作,所以请不要说不需要两个循环 下面的代码片段等待大约2秒,然后一次打印61个50次 for(var i=0;i<1;i++) { for(var j=1;j<51;j++) { window.setInterval(function(){ console.log(10*i + j); }, 2000); }

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

下面的代码片段等待大约2秒,然后一次打印61个50次

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

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

你只是误解了
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=0
i++
,等等)然后,一旦你想停止,你必须通过
clearInterval
告诉浏览器停止

不过,这很难理解,因此根据您实际尝试完成的内容,可能有更好的方法。例如,如果您尝试跨多个数组进行迭代,交叉连接方式,您可以首先消除对其中一个迭代器的需要。或者您可以使用像RxJS这样的库来实现所需的值安


因为您计划在
2000ms
之后运行它们,“我该怎么做?”---只需安排下一个数字在较长的间隔后输出。我不知道怎么做。我以为循环的第一个版本应该这样做,为什么第一个版本要打印61。实际代码的问题与虚构代码的问题解决方法相同:只需增加间隔(但使用
setTimeout
)。在你能够做到这一点后-解决闭包中捕获变量的问题。现在检查“不必要”,查看第二个和第三个答案。谢谢你的答案,但我需要这两个循环,因为我也在做一些需要两个循环的事情。有没有办法使用两个循环打印出这些数字?outl中的
I
oop应该从
0
9
。我只是在这里简化了ti。@SanJeetSingh:你不需要两个循环——这只是一个实现细节。你真正需要的是打印两个独立的数字。只需在声明
I
的循环之外添加你的
var j
,然后更改递增逻辑以获得你正在寻找的行为。事实上,我编写了我的代码的简化版本。我更新了问题以反映一些更改,并展示了我真正想要做的事情。@SanJeetSingh:我用更多信息更新了我的答案。关键是要理解
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);
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); });