先看一段代碼:
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的曲線似乎呈現如下:
在前面很短相同的時間裏,同時打印excute,隨後time逐漸增加。
其實在A這個區塊內,也是滿足先進先出後進後出的邏輯的,一段近乎水平
的增長曲線(可以理解成前半部分,比如i取100個的時候,“幾乎”是同時log,這裏無窮小的時間可以理解成0,所以在A這個區域,我們肉眼看見的先進先出沒觀察到)
這裏用到setTimeout的知識點:
1、待加入隊列的消息和一個時間值(可選,默認為 0)。這個時間值代表了消息被實際加入到隊列的最小延遲時間。如果隊列中沒有其它消息並且棧為空,在這段延遲時間過去之後,消息會被馬上處理(能看肉眼看到的一致)。但是,如果有其它消息,setTimeout 消息必須等待其它消息處理完(所以為何10萬級for循環log的時候,我們會源源不斷的看見被打印)。因此第二個參數僅僅表示最少延遲時間,而非確切的等待時間