javascript事件迴圈機制EventLoop

Betsy_迪發表於2019-02-22

面試題:1到10 ,每隔一秒輸出一個

自執行函式
 for (var i=1; i<=10; i++) {
      (function (i) {
        setTimeout(() => console.log(i), 1000*i)
      })(i)
    }
複製程式碼
塊級作用域
 for (let i=1; i<=10; i++) {
      (function () {
        setTimeout(() => console.log(i), 1000*i)
      })()
    }
複製程式碼

其實面試官是想問js的同步程式設計以及非同步程式設計

JS中的同步程式設計和非同步程式設計

JS是單執行緒的(一個任務只能執行一次,當前任務沒有完成,下面的任務是不會進行處理的)

同步程式設計(sync:synchronize):任務是按照一件件的完成的,當前任務沒有完成,下面的任務不進行處理

非同步程式設計(async::當前任務在等待執行的時候,我們不去執行,繼續完成下面的任務,當下面的任務完成後,而是也到達等待的時間了,採取執行當前的任務

非同步程式設計

> 定時器是非同步程式設計的

> 所有的事件繫結也是非同步程式設計

> AJAX中有非同步程式設計

> 有些人把回撥函式當做非同步程式設計(理解起來比較牽強)

> 其餘的都是同步程式設計
複製程式碼

同步程式設計個非同步程式設計的核心原理

1、JS 中有兩個任務佇列(存放任務列表的空間就是任務佇列)

1)主任務佇列:同步執行任務(從上到下依次執行)

2)等待任務佇列:非同步執行任務

setTimeout(function () {
    console.log(1);
}, 50);

setTimeout(function () {
    console.log(2);
}, 10);

setTimeout(function () {
    console.log(3);
}, 30);

for (var i = 0; i < 100000000; i++) {
    //=>需要600MS~700MS
}
console.log(4);
//輸出4,2,3,1,先執行迴圈,因為定時器非同步程式設計,先放到等待佇列,然後瀏覽器取執行迴圈,執行完事再去執行定時器,按照時間先後順序執行

複製程式碼
for (var i = 1; i <= 5; i++) {
    setTimeout(function () {
        console.log(i);//輸出5次6
    }, (5 - i) * 10);
}

//=>[主任務佇列]
// i=1 建立一個定時器
// i=2 建立一個定時器
// i=3 建立一個定時器
// i=4 建立一個定時器
// i=5 建立一個定時器
// i=6 迴圈結束,此時主任務佇列中的方法都已經執行完成了,到等待任務佇列中找先到時間的方法,拿到主任務佇列中執行
// 執行它 function () {console.log(i);},i不是自己私有的,找全域性下的i(此時的i已經是6了)

//=>[等待任務佇列]
// 40MS後執行某方法
// 30MS後執行某方法
// 20MS後執行某方法
// 10MS後執行某方法
// 0MS後執行某方法

複製程式碼

for (var i = 0; i <oList.length; i++) {
    oList[i].onclick=function () {
        alert(i);
    }
}

for (var i = 1; i <= 5; i++) {
    ~function (i) {
        setTimeout(function () {
            console.log(i);
        }, (5 - i) * 10);
    }(i);
}
複製程式碼
for ( i = 1; i <= 5; i++) {
   ~function(i){ setTimeout(function () {
       console.log(i);//依次輸出5,4,3,2,1
   }, (5 - i) * 10);}(i)
}
複製程式碼

相關文章