1. 程式人生 > >關於for迴圈裡的計時器

關於for迴圈裡的計時器

也算是比較經典的面試題了

for(var i=0;i<5;i++){
   console..log(i)
}

//0,1,2,3,4

 for (var i = 0; i < 5; i++) {
            console.log(i, "for");
            setTimeout(function() {
               console.log(i, "interval");
            });
 }
console.log('同步')

//打印出這個順序,這是主要是因為JS的執行機制有關,由於是單執行緒的執行機制,也就是說,大家都排隊吧,第一個結束,第二個跟上。

也就是說,第一個人不結束,第二個就一直等著。。。這樣乾等也不是個辦法,所以設計者就考慮到了,那第一個沒結束,就把等待中的任務給掛起,然後繼續第二個任務,直到等待中的任務有返回結果了,再繼續等待中的任務。

這裡就要分同步任務和非同步任務了,貼了一下某位coder的blog,他寫的很接地氣:https://www.cnblogs.com/hahazexia/p/9446585.html

來說一下上面列印的順序,按順序執行,for迴圈是同步任務,首先執行,接下來遇到計時器,是非同步任務,放到佇列後面,然後往下執行console.log('同步’),這時候開始執行剛才放到任務佇列最後的計時器,當計時器執行的時候 i 這個變數,已經變成了5,所以會打印出5.

接下來第三段程式碼,需要再計時器裡打印出0,1,2,3,4

 for (var i = 0; i < 5; i++) {
            console.log(i, "for");
            (function(i) {
                setTimeout(function() {
                    console.log(i, "interval");
                });
            })(i);
        }
        console.log("同步");

聰明的你肯定已經想到了,用了一個閉包,改變了作用域,這時候每一次迴圈裡,i的值都會被儲存起來。

 for (var i = 0; i < 5; i++) {
            console.log(i, "for");
            (function(i) {
                setTimeout(function() {
                    console.log(i, "interval");
                }, i * 1000);
            })(i);
        }
        console.log("同步");

這裡就是間隔