无法在Node.js循环中设置超时

时间:2017-03-15 13:19:11

标签: javascript node.js asynchronous settimeout

在这里,我试图为每次迭代设置超时但我无法做到因为nodejs的性质。有没有办法做到这一点?

提前致谢



for (var i = 1; i <= 1000; i++) {
    setTimeout(function () { console.log('something') }, 3000); 
}
&#13;
&#13;
&#13;

3 个答案:

答案 0 :(得分:5)

它可以工作,但它会同时安排所有超时。

如果您想以3秒的间隔安排它们,请使用:

for (var i = 1; i <= 1000; i++) {
    setTimeout(function () { console.log('something') }, i * 3000);
}

如果您想在超时回调中使用i,请使用let代替var,如下所示:

for (let i = 1; i <= 1000; i++) {
    setTimeout(function () { console.log('something', i) }, i * 3000);
}

正如您在var中看到的那样,它会为每一行打印1001:

for (var i = 1; i <= 1000; i++) {
    setTimeout(function () { console.log('something', i) }, i * 3000);
}

顺便说一句,您可以使用箭头函数语法简化它:

for (let i = 1; i <= 1000; i++) {
    setTimeout(() => console.log('something', i), i * 3000);
}

另一种方法是做类似的事情 - 而不是同时安排所有1000个超时,创建一个间隔:

(() => {
    let i = 0;
    setInterval(() => {
        i++;
        console.log('something', i);
    }, 3000);
})();

外部闭包是为了防止i变量在外部作用域中可见。或者你可以使用这样的东西:

(() => {
    let i = 0;
    let f = () => {
        i++;
        console.log('something', i);
        setTimeout(f, 3000);
    };
    setTimeout(f, 3000);
})();

在最后一个示例中,作为超时回调调用的函数每次完成时都会自行调度。

有很多方法可以做到这一点,并且都有一些优点和缺点。

例如,如果回调的运行时间可能超过调用之间的间隔,则不应使用setInterval。当你使用setTimeout并在每个回调中安排自己时,这不会是一个问题,但另一方面,你可能在这种间隔中的精度较低。你需要测试哪种方法最适合你。

答案 1 :(得分:2)

&#13;
&#13;
{
        "_index": "test-index-2017.03.15",
        "_type": "logevent",
        "_id": "AVrSIU-U8za2OFJzSCwQ",
        "_score": null,
        "_source": {
           "@timestamp": "2017-03-15T14:21:21.9636228+01:00",
           "level": "Information",
           "messageTemplate": "HeartbeatEntry {@Data}",
           "message": "HeartbeatEntry HeartbeatEntry { ServiceName: \"Service A\", HeartbeatValue: 1 }",
           "fields": {
              "Data": {
                 "_typeTag": "HeartbeatEntry",
                 "ServiceName": "Service A",
                 "HeartbeatValue": 1
              },
              "MachineName": "DevServer01"
           }
        },
        "sort": [
           1489584081963
        ]
     }
&#13;
&#13;
&#13;

尝试这样的事情。 您的代码实际上可以正常工作,但等待3秒钟,所有这些代码将在下一次迭代完成之前等待大约1 ms

答案 2 :(得分:0)

我认为你真正想要的是setInterval

let runMeEveryThreeSeconds = function() {
  console.log('hello!')
}
let threeSecondTimer = setInterval(runMeEveryThreeSeconds, 3000)

计时器将永远运行,并且每三秒钟就会发出一次“你好!”字样。将打印到您的控制台。当您准备取消计时器时,您需要:

clearInterval(threeSecondTimer)