先看一段代码:

console.log('-',new Date().getTime())
    for(let i = 0;i<100;i++){
        setTimeout(function(){
          console.log('exeute');
          },100);
    }
    console.log('i',new Date().getTime())

执行结果:

- 1610778978900
i 1610778978901
100 exeute

看第一个log跟第二个log时间只相差了1ms,时间短到几乎间隔为0.

再看一段代码:

console.log('-',new Date().getTime())
    for(let i = 0;i<100000;i++){
        setTimeout(function(){
          console.log('exeute');
          },100);
    }
    console.log('i',new Date().getTime())

执行结果

- 1610779277393
i 1610779278304
4466 exeute

过一会再去看,期间程序一直在执行,电脑还差点卡死了...
- 1610779277393
i 1610779278304
13188 exeute
不出意外的情况下,你会最终看见打印结果逐渐增加到10万。

规律感觉如下:
一开始很快的增长到上千上万(几乎是同时进行的)
然后逐步递增到10万。

第二段代码log时间相差了911ms。
从eventLoop异步原理,先进先出,后进后出逻辑来看确实结果如我们所愿。但为何在第一段代码里,我们会同时看见打印了100次exeute呢?

log和时间time的曲线似乎呈现如下:
image
在前面很短相同的时间里,同时打印excute,随后time逐渐增加。
其实在A这个区块内,也是满足先进先出后进后出的逻辑的,一段近乎水平
的增长曲线(可以理解成前半部分,比如i取100个的时候,“几乎”是同时log,这里无穷小的时间可以理解成0,所以在A这个区域,我们肉眼看见的先进先出没观察到

这里用到setTimeout的知识点:
1、待加入队列的消息和一个时间值(可选,默认为 0)。这个时间值代表了消息被实际加入到队列的最小延迟时间。如果队列中没有其它消息并且栈为空,在这段延迟时间过去之后,消息会被马上处理(能看肉眼看到的一致)。但是,如果有其它消息,setTimeout 消息必须等待其它消息处理完(所以为何10万级for循环log的时候,我们会源源不断的看见被打印)。因此第二个参数仅仅表示最少延迟时间,而非确切的等待时间


健儿
79 声望4 粉丝

掌握好原生js。