为什么setTimeout只在循环中打印一次?

时间:2018-06-09 06:03:51

标签: javascript

From this document,我知道setTimeout会返回计时器的ID值。

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

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

我在控制台选项卡中获得以下内容:

Javascript console output

即。它打印了一次计时器ID,然后打印了5个'hello'实例。

输出不应该有timerID,hello,timerID,hello,....而不是?

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

3 个答案:

答案 0 :(得分:2)

您所看到的是由于Javascript控制台的REPL (Read-Eval-Print Loop)性质。

您希望从循环的每次迭代中看到所有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(...))返回值
  • 来自5个延迟console.log('hello')语句的分组输出

答案 1 :(得分:1)

之所以发生这种情况,是因为同步代码。当你运行for循环时,它正在执行setTimeout()5次,所以你得到了ID,然后在0.1秒(100 MS)之后执行它的代码。如果你想得到它的预测方式(ID&#34; Hello&#34; ID&#34; Hello&#34; ...)你将不得不使用await和异步函数。

答案 2 :(得分:1)

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

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