Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/454.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 控制台上setTimeout的随机行为。如何按顺序获取计数以及此行为的原因? for(变量i=0;i_Javascript_Events_Queue - Fatal编程技术网

Javascript 控制台上setTimeout的随机行为。如何按顺序获取计数以及此行为的原因? for(变量i=0;i

Javascript 控制台上setTimeout的随机行为。如何按顺序获取计数以及此行为的原因? for(变量i=0;i,javascript,events,queue,Javascript,Events,Queue,此代码正在生成计数的随机结果。为什么会出现这种行为?我可以做些什么来获得正确的有序计数。您连续启动五个计时器,并且都具有相同的延迟。我怀疑,如果您查看计时器打算何时启动的内部细节,它们都会有完全相同的目标时间,除非系统时钟在计时器实例化之间“滴答”一声 没有严格的计时器顺序,可以有效地同时开火。你所看到的只是几个定时器几乎同时开火,没有特定的顺序。这就像在同一时间燃放5个烟花,每个都有相同的导火索长度——它们都会在“大约”同一时间熄灭,但不能保证你首先点燃的烟花会首先点燃。这正是计时器的本质,最

此代码正在生成计数的随机结果。为什么会出现这种行为?我可以做些什么来获得正确的有序计数。

您连续启动五个计时器,并且都具有相同的延迟。我怀疑,如果您查看计时器打算何时启动的内部细节,它们都会有完全相同的目标时间,除非系统时钟在计时器实例化之间“滴答”一声

没有严格的计时器顺序,可以有效地同时开火。你所看到的只是几个定时器几乎同时开火,没有特定的顺序。这就像在同一时间燃放5个烟花,每个都有相同的导火索长度——它们都会在“大约”同一时间熄灭,但不能保证你首先点燃的烟花会首先点燃。这正是计时器的本质,最好不要与之抗争

如果你想在将来同时做很多事情,我建议你启动一个计时器,当它启动时执行所有想要的操作


如果你真的,真的需要额外的排序,但是为了让所有的东西都在“基本相同的时间”触发,你可以让每个计时器保留一个“前一个”计时器的引用,然后等待计时器先完成。不过这会很难看,我至少会尽量避免使用它。要么事件是独立的,在这种情况下顺序无关紧要,要么它们是相互依赖的,在这种情况下,您可能应该以不同的方式安排它们。

当脚本运行时,for循环正在运行,并且您正在一次初始化5个
setTimeout
s,每一个都会在1000毫秒后超时。因为它们都设置为同时运行,而且
setTimeout
甚至不精确到毫秒,所以超时顺序是不可预测的。另一个潜在的混淆因素是
警报
阻塞

如下面的注释所示,
setTimeout
s可能恰好按照设置的顺序运行,但这并不能保证,不同浏览器的行为可能不同。因此,如果要确保它们按照设置的顺序运行,请为每个迭代添加几毫秒:

for(变量i=0;i<5;i++){
功能计时器(j){
setTimeout(函数(){
控制台日志(j);
},1000+(j*12));
}
计时器(i);
}
控制台上setTimeout的随机行为,…以及原因 行为

如前所述,每个
setTimeout
的执行顺序不受保证,这是因为它们基于给定的延迟而不是以其启动顺序独立运行,因此可以随机触发

如何使计数有序

同样,如前所述,延迟的微小变化可能是一种解决方案,但是,出于同样的原因,也不能保证这一点,尽管延迟差异非常大


假设您希望以一定的“保证”顺序延迟运行大量函数,这里有一个解决方案,将函数存储在一个数组中,然后逐个执行

堆栈代码段-带有警报

var fn_arr=[];
for(设i=0;i<5;i++){
fn_arr.push(函数(){alert(i)})
};
setTimeout(函数(){
fn_arr.forEach((fn)=>fn())

}, 1000);描述代码的输出。“随机”没有帮助,也不准确。它是否曾经输出
10
?我不这么认为。没有随机性,你设置
var I=0;i<5仅显示这些数字。@sr9yar根据浏览器的不同,它可能是0到4之间的随机数字。顺便说一句,警报!==console@CertainPerformance,好吧,但这仍然不是一个“随机结果”:),更像是随机执行时间,因为我期望所有这些数字,但只有它们显示的顺序是混乱的。这不是他所要求的for@Milind:OP问为什么它会以一种不合适的顺序输出-我已经解释过了。然后我解释说,试图让它变得可预测不是一个好主意。你认为OP在问什么我还没有解决的问题?对我来说不是,当我在堆栈片段或JSFIDLE上运行它时。@NinaScholz:你所说的“同步”到底是什么意思?@brk:这可能取决于浏览器和操作系统。对于我(Windows,Chrome)来说,警报的出现顺序不可预测。对于我来说,在Chrome 66.0.3359.181上和Opera 53上都不同步。这里有一个链接,console.log按顺序记录输出,更改为警报时,顺序不会保持
for (var i = 0; i < 5; i++) {
  function timer(j) {
    setTimeout(function() {
      alert(j);
    }, 1000);
  }
  timer(i);
};