爲何要弄清楚線程和任務(宏、微)。咱們常常會被問到一個問題,就是當settimeout和http請求回調還有promise的執行順序。這裏就涉及到了這些知識點。以及爲何js過大影響dom渲染。html
本文適合有必定經驗的前端人員,對js運行機制有必定了解。前端
首先咱們要知道瀏覽器在渲染一個頁面的過程種涉及到哪些工做原理。瀏覽器是多進程工做原理,什麼是進程請自行學習(進程是內存分配的最小單位),一個進程又能夠有多個線程(線程是執行的最小單位)。每打開一個tab標籤就是新啓一個進程(內存是獨立的)。node
知道了瀏覽器進程,那麼說一下一個進程的渲染過程:web
注意:這些都是屬於瀏覽器的與js引擎單線程同樣是屬於瀏覽器的segmentfault
GUI渲染線程與JS引擎線程是互斥的。因此會JS若是執行時間過長就會阻塞頁面。promise
那麼咱們就能夠理解了,咱們常常遇到的問題,就是當js執行的時候遇到時間定時器、異步加載等,他們的輸出結果會在頁面全部js執行以後執行的問題了,就是當遇到到時間定時器、異步加載等瀏覽器的事件觸發線程就會觸發他會產生一個任務添加到js的任務對列內,同理異步http請求線程、事件觸發線程也是同樣的。瀏覽器
由進程產生的非js引擎的任務會分紅宏、微兩種任務對列。bash
宏任務包括有:setTimeOut、setInterval、setImmediate、I/O、用戶交互操做,UI渲染網絡
微任務包括有:Promise(重點)、process.nextTick(nodejs)、Object.observe(不推薦使用)多線程
運行順序是當js單線程執行完成以後就會去執行任務對列的內容。當有宏微都有的時候執行是,先執行宏觀任務對列內的第一個任務,在執行所有的微觀任務,在執行宏觀任務對列內的第一個任務,在去執行所有微觀任務。因此下面的代碼輸出結果是這個樣子的:
console.log(1)
setTimeout(function() {
//settimeout1
console.log(2)
}, 0);
const intervalId = setInterval(function() {
//setinterval1
console.log(3)
}, 0)
setTimeout(function() {
//settimeout2
console.log(10)
new Promise(function(resolve) {
//promise1
console.log(11)
resolve()
})
.then(function() {
console.log(12)
})
.then(function() {
console.log(13)
clearInterval(intervalId)
})
}, 0);
//promise2
Promise.resolve()
.then(function() {
console.log(7)
})
.then(function() {
console.log(8)
})
console.log(9)
複製代碼
結果: 1,9,7,8,2,3,10,11,12,13
這裏注意: promise2執行,它的兩個then函數加入宏隊列
Web Worker 的做用,就是爲 JavaScript 創造多線程環境,容許主線程建立 Worker 線程,將一些任務分配給後者運行。具體怎麼使用請自行學習。
Web Worker 有如下幾個使用注意點:
本文是是本身學習筆記,若有看不懂的可參考如下連接。
參考文章連接以下:
一、瀏覽器以及js運行原理:segmentfault.com/a/119000001…
二、宏觀任務和微觀任務原理:juejin.im/post/5da742…
三、Web Worker使用:www.ruanyifeng.com/blog/2018/0…