淺談JavaScript巨集任務和微任務執行順序
目錄
- 一、javascript單執行緒
- 1. 同步任務(synchronous)
- 2. 非同步任務(asynchronous)
- 二、任務佇列(task queue)
- 1.執行棧
- 擴充套件一下setTimeout的理解
一、javaScript單執行緒
JavaScript是單執行緒指的是同一時間只能幹一件事情,只有前面的事情執行完,才能執行後面的事情。導致遇到耗時的任務時後面的程式碼無法執行。
在此之前啊 我們必須瞭解同步和非同步
1. 同步任務(synchronous)
console.log(123); console.log(456); for (let i = 1; i <= 5; i++) { console.log(i); }
顧名思義 得到的一定是 順序執行
2. 非同步任務(asynchronous)
setTimeout(() => {
console.lohttp://www.cppcns.comg('定時器');
},0)
console.log('奧特曼');
按普通的執行順序來說 定時器在上面 應該先輸出定時器 在輸出 奧特曼
最後拿到的結果卻先輸出奧特曼 在輸出了定時器 原因呢就是 setTimeout是非同步任務
補充一個知識點 setTimeout的定時器 不管延遲多少毫秒 也是非同步的 每個瀏覽器的時間也是不同的,各個瀏覽器都有差異 但定義了0 最小也是4毫秒
二、任務佇列(task queue)
通過上面程式碼知道setTimeout是非同步的 我們就搞清了執行順序優先順序 同步程式碼>非同步程式碼 所以說 在任務佇列中 分為兩大類 1.同步任務 2. 非同步任務
1.執行棧
(1)所有同步任務都在主執行緒上執行,形成一個執行棧(execution context stack)。
(2)主執行緒之外,還存在一個"任務佇列"(task queue)。只要非同步任務有了執行結果,就在"任務佇列"之中放置一個事件。
(3)一旦"執行棧"中的所有同步任務執行完畢,系統就會讀取"任務佇列",看看裡面有哪些事件。那些對應的非同步任務,於是結束等待狀態,進入執行棧,開始執行。
(4)主執行緒不斷重複上面的第三步,稱為事件迴圈(Event Loop)。
簡單舉個梨子
同樣都是去吃飯 但是p2 省去了出去的時間過程
簡單瞭解後 我們再來深入瞭解 非同步任務中的 巨集任務(macrotask)和 微任務(microtask)
個人理解: 對於巨集任務和微任務 可以理解為兩種非同步的形態, 非同步有兩個孩子 巨集任務 和 微任務
巨集任務中的方法:1. script (可以理解為外層同步程式碼,作為入口 ) 2. setTimeout/setInterval
微任務中的方法:1.Promise 2. nextTick
而他們的執行順序 是 微任務 先輸出 在輸出 巨集任務
口說無憑 上程式碼
setTimeout(() => { console.log('定時器'); },0) new Promise((resolve) => { console.log('同步程式碼') resolve('非同步程式碼') }).then((res) => { console.log(res); }) console.log('奧特曼');
注意奧 new Promise是建立一個建構函式 這個過程是同步的,而.then方法是非同步的 所以程式碼先執行 同步>微任務>巨集任務
為了更加詳細 用圖來描述執行過程 下面的圖有一丁丁大 學習不怕費流量哦
這些圖在融合一下
擴充套件一下setTimeout的理解
疑問點1 同步程式碼執行完了 setTimeout會從0計時嗎
setTimeout(() => { console.log('setTimeout'); },1000); console.log('奧特曼'); for (let i = 0; i < 1000; i++) { console.log(''); }
此時要表明的是 我在for迴圈的時候setTimeout也會去計時 他會去開啟一個定時器模組 ,所以說執行主執行緒的時候,定時器模組已經開始執行了,所以不會再去等待1秒去執行
(千萬別以為同步執行完了,再去計時哦)
疑問點2:兩個定時器 上面的定時器先執行 在執行下面的定時器嗎?
測驗我們只修要在加一個定時器 看看誰先執行就好了
setTimeout(() => { console.log('setTimeout1'); },2000)程式設計客棧; setTimeout(() => { c程式設計客棧onsole.log('setTimeout2'); },1000);
結果發現 如果有兩個定時器,時間少的會優先放到主執行緒裡去執行
疑問點3:定義一個變數為0 設定兩個一樣的定時器事件 他會輸出什麼結果 ? (面試題)
i = 0 setTimeout(() => { console.log(++i); //1 },1000); setTimeout(() => { console.log(++i); //2 },1000);
看到現在 肯定要知道 定時器巨集任務不是一起執行的 依次執行!!
巨集任務、微任務 執行順序面試題
console.log('1');
setTimeout(function () {
console.log('2');
process.nextTick(functi程式設計客棧on () {
console.log('3');
})
new Promise(function (resolve) {
console.log('4');
resolve();
}).then(function () {
console.log('5')
})
})
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
第三輪 巨集任務 第一個setTimeout : 同步2 4 微任務 3 5 第二個setTimeout:同步 9 11 微任務 10 12
整體答案: 1、7 、6、8、2、4、3、5、9、11、10、12
到此這篇關於淺談JavaScript巨集任務和微任務執程式設計客棧行順序的文章就介紹到這了,更多相關JavaScript巨集任務和微任務執行順序內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!