javascript setTimeout() - 在 for 循环中随机延迟

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10242254/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 09:10:05  来源:igfitidea点击:

setTimeout() - in for loop with random delay

javascriptclosuressettimeout

提问by Pierre de LESPINAY

Possible Duplicate:
Javascript closure inside loops - simple practical example

可能的重复:
循环内的 Javascript 闭包 - 简单的实际示例

Seen many posts talking about setTimeoutand closures but I'm still not able to pass in a simple for loop counter.

看到很多关于setTimeout闭包的帖子,但我仍然无法传递一个简单的 for 循环计数器。

for (i = 0; i < 5; i++) {
  setTimeout(function () {
    console.log(i);
  }, Math.floor(Math.random() * 1000));
}

Gives

5
5
5
5
5

5
5
5
5
5

Would like to have

想拥有

0
1
2
3
4

0
1
2
3
4

What's wrong ?
Please don't flame, I thought I have understood the setTimeout()tale but apparently not.

怎么了 ?
请不要发火,我以为我已经理解了这个setTimeout()故事,但显然没有。

回答by James Allardice

You can use a closure to keep a reference to the current value of iwithin the loop:

您可以使用闭包来保持i对循环内当前值的引用:

for (i = 0; i < 5; i++) {
    (function(i) {
        setTimeout(function () {
            console.log(i);
        }, Math.floor(Math.random() * 1000));
    })(i); //Pass current value into self-executing anonymous function
}?

However, this is unlikely to print the numbers in order since you use a random timeout (you could use i * 1000instead to make the numbers print in ascending order, one second apart).

但是,这不太可能按顺序打印数字,因为您使用了随机超时(您可以使用i * 1000以升序打印数字,相隔一秒)。

Here's a working example.

这是一个工作示例

回答by Jamie Dixon

You need to pass ito the function being used in the setTimeout. By the time your first method is executed, iis already set to 5.

您需要传递isetTimeout. 执行第一个方法时,i已设置为 5。

Since your timeout is variable due to the call to Math.Random(), the timeouts will be different and you won't get them in the sequence you're expecting.

由于您的超时因调用而发生变化Math.Random(),因此超时将有所不同,您不会按照预期的顺序获得它们。

Here's a working example

这是一个工作示例

for (i = 0; i < 5; i++) {
    (function(i) {
        setTimeout(function () {
            console.log(i);
        }, 1000);
    })(i);
}

Changing Math.floor(Math.random() * 1000)to simply 1000ensures that the functions execute in the order you're expecting.

更改Math.floor(Math.random() * 1000)为只是1000确保函数按您期望的顺序执行。

回答by Jon

You need to wrap the "interesting" code in a function that closes over iand copies it in a local variable:

您需要将“有趣”的代码包装在一个关闭的函数中i并将其复制到局部变量中:

for (i = 0; i < 5; i++) {
  (function() {
    var j = i;
    setTimeout(function () {
      console.log(j);
    }, Math.floor(Math.random() * 1000));
  })();
}

The "intermediate" function call forces the value of jto be fixed at the point that function is called, so within each setTimeoutcallback the value of jis different.

“中间”函数调用强制在调用函数时j固定的值,因此在每个setTimeout回调中, 的值j是不同的。