setTimeout 在循环中,它的行为与预期不同

setTimeout in a loop, it behaves different than expected

本文关键字:循环 setTimeout      更新时间:2023-09-26

所以我知道setTimeout()函数可以在一段时间后触发传入的函数,但它在循环中的行为似乎有所不同。例如:

for (var i = 0; i < 5; i++) {
  setTimeout(console.log(i + ', time is: ' + new Date()), 1000);
}

控制台.log() 似乎同时打印出所有数字。我不明白为什么。你们中的一些人可以解释为什么setTimeout()在这个循环中不起作用吗?

您没有将console.log传递给setTimeout,而是立即调用它。

此外,您需要将i置于关闭状态,否则所有调用都将记录5

试试这个:

function makelogger(i) {
    return function () {
        console.log(i + ', time is: ' + new Date());
    }
}
for (var i = 0; i < 5; i++) {
    setTimeout(makelogger(i), 1000); // or i*1000
}

如果你想每秒执行控制台功能,你需要做一些不同的事情。

    for (var i = 1; i <= 5; i++) 
    {
      setTimeout( function() 
      {
        document.write(new Date() + "<br />");
      }, (i * 1000));
    }

这将以 1 秒的间隔显示时间,总共 5 次。

在你的setTimeout中,第一个参数应该返回一个稍后将执行的函数。因此,您需要一个表达式,该表达式将是函数调用,而不是函数调用本身。

尝试,作为一个粗略的例子:(ttl是活:)的考验

function makelogger(ttl) {
    var msg = ttl + ', time is: ' + new Date();
    console.log(msg);
    if ( ttl > 0 ) {
      setTimeout(function(){return makelogger(ttl-1)}, 1000); 
    }
}
makelogger(5)

这是完整的 MDN 描述

问题的解决方案是将函数包装到闭包中:

for (var i = 1; i <= 5; i++) 
{  
    (function(j)
    {
        setTimeout(function() 
        {
            document.write(j + " - " + new Date() + "<br />");
        }, (j * 1000));
    })(i);      
}

您可以链接您的设置超时:

  setTimeout(function() {
    console.log(1 + ', time is: ' + new Date())
    setTimeout(function() {
        console.log(2 + ', time is: ' + new Date())
    }, 1000);
  }, 1000);

或者你可以使用一个函数来让它变得更好:

times = 5;
timeout(times);
function timeout(times) {
    setTimeout(function(){
        console.log(times + ', time is: ' + new Date())
        if(times > 1) {
            setTimeout(timeout(times-1), 1000);
        }
    },1000) 
}