淺談js運行機制

js最大的特點就是單線程,也就是說同一時間只能做一件事。原因在于js主要用途是與用戶互動,操作DOM。假如是多線程,一個線程想刪除DOM,而另一個線程想在這個DOM上增加內(nèi)容,這樣的話就會矛盾。所以注定是單線程。

為了提高多核CPU的計算能力,HTML5提出Web Worker標準,允許js腳本創(chuàng)建多個線程,但是子線程完全受主線程控制,且不得操作DOM。所以,這個新標準并沒有改變js單線程的本質(zhì)。

既然js是單線程,那么不管有多少任務,都要排隊,只有一個任務完成,下一個任務才能執(zhí)行。如果任務耗時很長,那么就要一直等待。但很多時候CPU是閑著的,例如AJAX獲取數(shù)據(jù)是很慢的,只能一直等到數(shù)據(jù)返回才能執(zhí)行下個任務。

所以js設計者意識到這時完全可以把等待中的任務掛起,先執(zhí)行后續(xù)任務,等返回結果后再執(zhí)行該任務。

于是,把任務分為同步任務和異步任務。同步任務指在主線程排隊的任務,只有一個執(zhí)行完后才會執(zhí)行下一個任務。異步任務指的是,不進入主線程,而是進入任務隊列的任務,只有當任務隊列通知主線程,某個異步任務可執(zhí)行的時候,主線程才會執(zhí)行這個任務。

任務的運行機制:

(1)所有同步任務都在主線程上,形成一個執(zhí)行棧;

(2)除主線程外,還有一個任務隊列。只要異步任務執(zhí)行有了結果,會在任務隊列中放一個事件;

(3)當主線程上的所有同步任務執(zhí)行完成后,會去讀取任務隊列,看里面有哪些事件,那些對應的異步任務,結束等待狀態(tài),進入主線程被執(zhí)行。

(4)主線程不斷重復以上三步。

不得不說一下定時器的使用,可以設置一段時間后再執(zhí)行事件。

如果將第二個參數(shù),也就是推遲執(zhí)行的毫秒數(shù),設置為0時,表示當前代碼執(zhí)行完后,立即執(zhí)行回調(diào)函數(shù),而這里的“當前代碼執(zhí)行完”,指的是執(zhí)行棧中的所有任務執(zhí)行完成。

setTimeout(fn,0)的含義是,指定某個任務在主線程最早可得的空閑時間執(zhí)行,也就是說,盡可能早得執(zhí)行。它在任務隊列的尾部添加一個事件,因此要等到同步任務和任務隊列現(xiàn)有的事件都處理完,才會得到執(zhí)行。

HTML5標準規(guī)定了setTimeout()的第二個參數(shù)的最小值(最短間隔),不得低于4毫秒,如果低于這個值,就會自動增加。使用setTimeout()只是將事件插入了任務隊列,并不能保證在推遲執(zhí)行的毫秒數(shù)后立即執(zhí)行,因為前面的任務有可能耗時很長。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容