0

从这个文档中,我了解到setTimeout返回计时器的 ID 值。

但是当我运行这段代码时:

for (var i = 1; i <= 5; i++) {
    setTimeout(function() { console.log('hello'); }, 100);
}

我在控制台选项卡中得到以下信息:

Javascript 控制台输出

即它打印了一次计时器 ID,然后打印了 5 个连续的“hello”实例。

输出不应该有 timerID, hello, timerID, hello, .... 代替吗?

为什么setTimeout即使在循环中也只打印一次它的 ID?

4

3 回答 3

2

您所看到的是由于 Javascript 控制台的REPL(读取-评估-打印循环)性质。

您期望setTimeout()从循环的每次迭代中看到所有调用的结果。但是,在完成一组语句后,JS 控制台只打印出最近执行的语句的返回值。

此行为的简单展示:

注意:在这些示例中,我描述的是 JS 控制台输入/输出,而不是包含可执行代码块,因为所讨论的行为特定于交互式使用控制台。

>  x = 4;
<- 4

>  y = 5;
<- 5

>  x; y;
<- 5

在最后一条命令中有两条语句,只打印最后一条的值。

如果你想打印出每个setTimeout()调用的 id,你只需要显式地执行日志操作:

>  for (var i = 1; i <= 5; i++) {
     console.log(setTimeout(function() { console.log('hello'); }, 100));
   }
596
597
598
599
600
<- undefined
5  hello

上面你看到:

  • console.log(setTimeout(...))立即执行的语句的 5 个输出
  • 最后一条语句的undefined返回值console.log(setTimeout(...))
  • console.log('hello')5 个延迟语句的分组输出
于 2018-06-09T06:21:40.040 回答
1

发生这种情况的原因是因为同步代码。当您运行 for 循环时,它会执行 setTimeout() 5 次,因此您会获得 ID,并在 0.1 秒(100 毫秒)后执行其代码。如果你想得到你预测的结果(ID "Hello" ID "Hello" ... ),你将不得不使用 await 和一个异步函数。

于 2018-06-09T06:11:56.187 回答
1

该函数setTimeOut返回一个值,因此它不会显示在控制台中,除非您为其分配一个变量然后输出该变量。

for (var i = 1; i <= 5; i++) {
    let delay = setTimeout(function() { console.log(delay,'hello'); }, 100);
}

于 2018-06-09T06:19:49.420 回答