深入理解JS執行機制

2021-10-02 14:02:22 字數 1798 閱讀 9233

js為什麼是單執行緒的?

js最初被設計用在瀏覽器中,那麼想象一下,如果瀏覽器中的js是多執行緒的。

場景描述:

那麼現在有2個執行緒,process1 process2,由於是多執行緒的js,所以他們對同乙個dom,同時進行操作

process1 刪除了該dom,而process2 編輯了該dom,同時下達2個矛盾的命令,瀏覽器究竟該如何執行呢?

這樣想,js為什麼被設計成單執行緒應該就容易理解了吧。

js為什麼需要非同步?

場景描述:

如果js中不存在非同步,只能自上而下執行,如果上一行解析時間很長,那麼下面的**就會被阻塞。

對於使用者而言,阻塞就意味著"卡死",這樣就導致了很差的使用者體驗

js單執行緒又是如何實現非同步的呢?

其實本質就是通過js的事件迴圈來實現的,也可以將此理解為js的執行機制

備註:js**可以有兩種分類,一種是分為同步**和非同步**,還有一種更為精確的分類是分為巨集任務和微任務,今天我們要講的就是後一種。。。

剛提到了巨集任務和微任務,那麼哪些**屬於巨集任務?哪些屬於微任務呢?

巨集任務:包括整體**script,settimeout,setinterval

微任務:promise(then語句),process.nexttick

js的執行機制是:

總結:就是執行乙個巨集任務,把所有微任務執行完算乙個迴圈,重複以上兩個步驟,這就是js的事件迴圈,理解一點了嗎?

好,接下來講完了理論知識,我們就來進行一些實戰練習,看一些例子鞏固下:

demo1:

console.log(1)

settimeout(function(),0)

console.log(3) //執行結果是:1,3,2

**解析:

這個例子中,當執行第一句**時,就進行了第乙個巨集任務的執行(普通js**),所以按順序從上往下執行,首先輸出1,然後遇到settimeout,將該段**先暫時放到巨集任務的事件佇列中,然後接著往下執行,輸出3,當第一輪的巨集任務執行完成後,會去微任務的事件佇列中去尋找有沒有要執行的**,很明顯,此時沒有,所以第一輪的事件迴圈結束,開始第二輪的事件迴圈,執行第二個巨集任務(也就是剛才的settimeout),於是最後輸出的就是2,所以最終結果就是1,3,2

demo2:

settimeout(function());

new promise(function(resolve)

}).then(function());

console.log('4');

**解析:

這個例子中,同樣也是一開始執行js**時(第乙個巨集任務),遇到settimeout,將其放至巨集任務的事件佇列中,promise函式中的**是同步立即執行的,所以此時第乙個輸出的是2,然後執行到then語句時,它屬於微任務,所以將其放到微任務的事件佇列中,遇到console.log(4)同步**也是立即執行,到這第乙個巨集任務執行完成了,然後去微任務事件佇列中去尋找有沒有要執行的**,也就是剛才的then語句,於是輸出3,此時第一輪的事件迴圈結束了,開始執行第二個巨集任務(settimeout**),於是輸出1,所以最終這段**的輸出結果是2,4,3,1

深入理解JS引擎的執行機制

1 js是單執行緒語言 2 js的event loop是js的執行機制。深入了解js的執行,就等於深入了解js裡的event loop 技術的出現,都跟現實世界裡的應用場景密切相關的。同樣的,我們就結合現實場景,來回答這三個問題 1 js為什麼是單執行緒的?js最初被設計用在瀏覽器中,那麼想象一下,...

JS執行機制

js是單執行緒的,settimeout和setinterval是非同步任務,要掛起,不先執行,等同步任務完成之後,再去處理非同步任務 console.log 1 settimeout function 0 console.log 3 console.log 4 輸出 1 3 4 2console.l...

JS執行機制

輸出結果為 1,2,3 js是從上到下執行的 js是單執行緒的,即在同一時間只能做一件事情 遇到同步程式,直接執行 遇到非同步程式,先掛起,等同步程式執行完畢後再執行 同步佇列 優先順序最高 非同步佇列 遇到非同步佇列先掛起,等同步佇列執行完後,再選擇執行非同步佇列的某個 settimeout中的時...