node中的setTimeout,setInterval,promise.then和process.nextTick()的執行順序。
1.關於javaScript的單執行緒:
應用場景決定了javascript的單執行緒的特性,假如javascript是多執行緒,同時進行:一個執行緒對某一個dom進行新增屬性操作,另一個執行緒對該執行緒進行刪除操作,那麼瀏覽器該聽哪一個。這就決定javascript必須是單執行緒。
web worker:是一個多執行緒。它出現的目的是當瀏覽器有大量密集的計算時候或者響應時間很長的運算時候,頁面出現卡頓,可以起一個worker子執行緒,主執行緒和worker執行緒互不干預,這樣頁面就可以進行點選之類的操作,但這個子執行緒不能操作DOM元素。
2.javascript事件迴圈:
同步任務:直接通過主執行緒執行,如script程式碼
非同步任務: 進入Event Table,並註冊回撥函式——> Event Queue,等主執行緒的執行棧為空時候,讀取Event Queue裡面的函式就,進入主執行緒。如setTimeout,promise.then()等;
那怎麼知道主執行緒的執行棧為空呢,JS引擎存在monitoring process
let data = [];
$.ajax({
url:www.javascript.com,
data:data,
success:() => {
console.log('傳送成功!');
}
})
console.log('程式碼執行結束');
- ajax進入Event Table,註冊回撥函式success。
- 執行console.log(‘程式碼執行結束’)。
- ajax事件完成,回撥函式success進入Event Queue。
- 主執行緒從Event Queue讀取回調函式success並執行。
3.setTimeout和setInterval
setTimeout(() => { a() },3000)
b(10000000)//b代表一個執行需要耗時很久的函式
- a進入Event Table,註冊回撥函式success。
- 執行b函式,但是b函式執行時間超出了3秒鐘
- 3秒鐘到了,success進入Event Queue,但是以為主執行緒沒有執行完,只能等。
- b函式執行完了,主執行緒從Event Queue讀取回調函式success並執行。
有時候我們這樣寫:setTimeout(()=>{},0),即使主執行緒執行棧是空的,這個並不是立即0毫秒執行,setTimeout有最小時間間隔限制,HTML5標準為4ms,小於4ms按照4ms處理,但是每個瀏覽器實現的最小間隔都不同.setInterval最小時間間隔為10ms;
4.promise與process.nextTick();
巨集任務:上面我們說到的script程式碼,setTimeout,setInterval。
微任務:promise.then(),process.nextTick();且preocess.nextTick優先順序大於promise.then;
console.log('1');
setTimeout(function() {
console.log('2');
new Promise(function(resolve) {
console.log('4');
resolve();
}).then(function() {
console.log('5')
})
process.nextTick(function() {
console.log('3');
})
})
process.nextTick(function() {
console.log('6');
})
new Promise(function(resolve) {
console.log('7');
resolve();
}).then(function() {
console.log('8')
})
setTimeout(function() {
console.log('9');
process.nextTick(function() {
console.log('10');
})
new Promise(function(resolve) {
console.log('11');
resolve();
}).then(function() {
console.log('12')
})
})
1
7
6
8
2
4
9
11
3
10
5
12
總結:
1.先是巨集任務-->微任務-->巨集任務-->微任務一直迴圈下去;
2.script程式碼為第一層巨集任務,如果有setTimeout,setInterval,則他們的回撥函式會成為第二層的巨集任務,
3.promise.then()和process.nextTick()是微任務,在執行完該一層的巨集任務後執行,且process.nextTick()優先於promise.then();