最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS的運行機制之事件循環(huán)機制示例詳解

 更新時間:2025年07月21日 10:54:05   作者:小陳同學的前端基地  
事件循環(huán)是JavaScript實現(xiàn)異步編程的核心,通過單線程執(zhí)行模型協(xié)調同步代碼、回調隊列、異步事件及微任務和宏任務,這篇文章主要介紹了JS運行機制之事件循環(huán)機制的相關資料,需要的朋友可以參考下

前言

在現(xiàn)代Web開發(fā)中,JavaScript是構建動態(tài)交互體驗的核心。但它的運行機制卻常被誤解——一個看似“單線程”的語言如何高效處理復雜的異步操作?JavaScript 是一門以事件驅動、單線程執(zhí)行為核心特征的編程語言。盡管它在執(zhí)行代碼時只有一個主線程,但卻能高效地處理各種異步任務,如定時器、網(wǎng)絡請求、用戶交互等。這背后,正是強大的事件循環(huán)機制在默默運轉。本文將從瀏覽器的進程模型開始,逐步揭開 JavaScript 事件循環(huán)的神秘面紗。

一、進程和線程

1.1進程和線程的基本概念

要想了解JavaScript的運行機制,首先得了解進程和線程是什么

進程(Process)是操作系統(tǒng)分配資源的基本單位

線程(Thread) 是程序執(zhí)行的最小單位,一個進程中可以包含多個線程,共享內存資源。

  一個應用至少一個進程,每個進程之間相互獨立,進程之間共享內存空間。

  一個進程至少一個線程,進程開啟后會自動創(chuàng)建一個線程來運行代碼,稱為主線程。要是程序需要同時執(zhí)行多塊代碼,就需要啟動動更多線程來執(zhí)行代碼,所以一個進程可以包含多個進程。

而JavaScript本身就是 運行在瀏覽器中,而瀏覽器本身也是一個多進程、多線程的復雜應用

1.2 瀏覽器的多進程架構

現(xiàn)代瀏覽器(如 Chrome)采用多進程架構,其主要進程包括:

瀏覽器主進程:負責地址欄、書簽欄、前進后退、標簽管理等 UI 操作。

網(wǎng)絡進程:處理網(wǎng)絡資源的下載(如 HTML、CSS、JS、圖片等)。

渲染進程:每打開一個標簽頁,通常會分配一個獨立的渲染進程,負責頁面渲染與 JavaScript 執(zhí)行。

GPU進程:處理與圖形渲染相關的任務,包括3D CSS效果、頁面UI的GPU加速繪制,以及視頻解碼等

 插件進程(Plugin Process):獨立運行瀏覽器插件(如Flash、廣告攔截工具),防止插件崩潰影響瀏覽器或其他頁面

輔助進程(根據(jù)場景啟動):跨頁面共享的JavaScript線程,獨立于渲染進程管理

瀏覽器插件種類繁多,但我們需要重點掌握JavaScript的運行機制。這就要從關鍵的渲染進程入手,它與前端頁面渲染密切相關。

1.3 渲染進程中的主線程

渲染進程內部,核心是渲染主線程,它負責:

解析 HTML,構建 DOM 樹

解析 CSS,構建 CSSOM

執(zhí)行 JavaScript

計算樣式、布局、繪制

JavaScript 的運行環(huán)境就在這個主線程中。因此,JavaScript 是單線程執(zhí)行。

二、異步機制

JavaScript 只運行在瀏覽器的渲染主線程中,渲染主線程就只有一個,而這個線程既要負責腳本執(zhí)行,又要承擔頁面渲染、事件響應等工作。試想一下,如果我們讓 JS 主線程一直執(zhí)行某個任務(比如復雜的循環(huán)),那其他任務(如用戶點擊)就無法響應,頁面也無法渲染更新,用戶體驗會極差。

2.1 同步的代價

我們先來分析一段代碼

while (true) {
  // 模擬高消耗運算
}

這段代碼是一個死循環(huán),它將讓頁面徹底卡死,因為主線程被死循環(huán)阻塞,無法響應任何操作。

2.2 異步機制的引入

為了防止主線程長時間阻塞,JavaScript 借助瀏覽器的其他線程(如計時器線程、網(wǎng)絡線程等)來異步處理任務:

1.主線程將異步任務交由其他線程執(zhí)行(如 setTimeout 的計時由 Web APIs 中的 Timer 線程負責)。

2.等任務完成后,將“回調函數(shù)”包裝成任務加入任務隊列。

3.主線程空閑后,從任務隊列中取出這些任務執(zhí)行。

這樣就實現(xiàn)了非阻塞的異步模型。

2.3 異步機制的解讀

JavaScript 是一門單線程語言,因為它運行在瀏覽器的渲染主線程上,而該線程是唯一的。

渲染主線程需要處理多項任務,包括頁面渲染和執(zhí)行 JavaScript 代碼等。如果采用同步執(zhí)行方式,可能會導致主線程阻塞,進而使消息隊列中的其他任務無法及時執(zhí)行。這不僅會造成主線程資源的浪費,還會導致頁面更新延遲,給用戶帶來卡頓的體驗。

為此,瀏覽器采用異步機制來解決這個問題。當遇到計時器、網(wǎng)絡請求、事件監(jiān)聽等任務時,主線程會將這些任務交由其他線程處理,自身則繼續(xù)執(zhí)行后續(xù)代碼。待其他線程完成任務后,會將回調函數(shù)封裝成新任務,添加到消息隊列末尾等待主線程調度執(zhí)行。

這種異步機制有效避免了瀏覽器阻塞,確保了單線程運行的流暢性。

三、事件循環(huán)機制

3.1 事件循環(huán)(event loop)

事件循環(huán)是瀏覽器或 Node.js 中控制異步執(zhí)行的核心機制。它的本質就是一個不斷循環(huán)的系統(tǒng):

while (true) {
  // 1. 執(zhí)行一個宏任務(task)
  // 2. 執(zhí)行完立即清空所有微任務(microtasks)
  // 3. 如果需要更新界面,則進行渲染
}

每一次完整的循環(huán)稱為一個“tick”。在每個 tick 中,主線程都會從任務隊列中取出一個宏任務執(zhí)行,并在其執(zhí)行完畢后立即清空微任務隊列。

3.2 任務隊列

現(xiàn)代瀏覽器不再僅使用“宏任務隊列 + 微任務隊列”的模型,而是根據(jù)任務來源將宏任務進一步拆分成多個隊列,例如:

延時隊列:setTimeout, setInterval

用戶交互隊列:如 click、input 等事件

UI 渲染隊列:requestAnimationFrame

網(wǎng)絡事件隊列:fetch、xhr

這些消息隊列中的任務采用先進先出機制,沒有獨立優(yōu)先級,但消息隊列本身具有優(yōu)先級劃分。

每個任務都有特定類型,同類型任務必須歸入同一隊列,不同類型任務可分配到不同隊列。在單次事件循環(huán)中,瀏覽器可根據(jù)實際情況從不同隊列中選取任務執(zhí)行。

瀏覽器必須維護專門的微隊列,該隊列中的任務享有最高執(zhí)行優(yōu)先級。

當前主流隊列按優(yōu)先級排序為:延時隊列(中優(yōu)先級)、交互隊列(高優(yōu)先級)、微隊列(最高優(yōu)先級)。

3.3 瀏覽器中一輪事件循環(huán)的過程

根據(jù)上述對事件循環(huán)和異步任務的解釋,可以得出瀏覽器中的一輪事件的循環(huán)過程

  1. 取出一個宏任務執(zhí)行

  2. 執(zhí)行過程中可能注冊多個微任務(如 Promise.then)

  3. 執(zhí)行完宏任務后,立即依次執(zhí)行所有微任務

  4. 執(zhí)行 UI 更新與渲染

  5. 進入下一輪循環(huán),重復上述流程

四、相關問題的解答

1. JS為什么會阻塞渲染

由于 JS 腳本的執(zhí)行與頁面渲染共用主線程,若 JS 長時間執(zhí)行,渲染任務就會延后。

例如以下同步阻塞代碼:

while(Date.now() < performance.now() + 2000) {}

頁面會在 2 秒內完全無法響應。

此外,瀏覽器為了防止 JS 操作 DOM 導致的視覺中斷,在 JS 執(zhí)行期間通常會“暫停渲染”,等腳本執(zhí)行完畢再統(tǒng)一渲染頁面。

2. JS的計時器能做到真正的精確計時嘛

(1)計算機硬件和操作系統(tǒng)的限制

        CPU時鐘精度問題,計算機沒有原子鐘,無法精確計算時間

        操作系統(tǒng)提供的計時 API(如 Windows 的 GetSystemTime)存在 1-15ms 的調用誤差。

(2)瀏覽器的引擎機制

        嵌套超限補償,當定時器嵌套層級超過 5 層時(如回調中再次調用 setTimeout),瀏覽器會強制增加 4ms 延遲:

// 假設這是第六次調用,調用開始產(chǎn)生額外延遲,即使設置延遲為0,也會有至少4ms延遲
setTimeout(function recur() {
  setTimeout(recur, 0); // 實際延遲 ≥4ms
}, 0);

        最小時間間隔,即使設置 setTimeout(fn, 0),實際延遲通常被限制為 1ms(Chrome)或 4ms(舊版瀏覽器)。

(3)事件循環(huán)調度延遲

        主線程阻塞,當同步代碼或長任務占用主線程時,計時器回調必須等待。   

        隊列優(yōu)先級競爭,即使準時到期,回調仍需等待:微任務隊列清空、更高優(yōu)先級的交互/動畫任務、當前執(zhí)行棧為空。

總結

到此這篇關于JS的運行機制之事件循環(huán)機制的文章就介紹到這了,更多相關JS事件循環(huán)機制內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Bootstrap彈出框(Popover)被擠壓的問題小結

    Bootstrap彈出框(Popover)被擠壓的問題小結

    比較了下Bootstrap的popover和一些其它的開源項目,覺得Bootstrap的還算不錯。在使用過程中遇到了一系列問題,下面小編給大家分享Bootstrap彈出框(Popover)被擠壓的問題小結,需要的朋友參考下吧
    2017-07-07
  • JS和css實現(xiàn)檢測移動設備方向的變化并判斷橫豎屏幕

    JS和css實現(xiàn)檢測移動設備方向的變化并判斷橫豎屏幕

    這篇文章主要介紹了JS和css實現(xiàn)檢測移動設備方向的變化并判斷橫豎屏幕,本文分別給出實現(xiàn)代碼,需要的朋友可以參考下
    2015-05-05
  • JSONObject使用方法詳解

    JSONObject使用方法詳解

    JSONObject-lib包是一個beans,collections,maps,java arrays和xml和JSON互相轉換的包,本文給大家介紹jsonobject使用方法相關知識,感興趣的朋友一起學習吧
    2015-12-12
  • Javascript單線程和事件循環(huán)

    Javascript單線程和事件循環(huán)

    這篇文章主要介紹了Javascript單線程和事件循環(huán),文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-06-06
  • JS實現(xiàn)基數(shù)排序的示例代碼

    JS實現(xiàn)基數(shù)排序的示例代碼

    基數(shù)排序是一種根據(jù)數(shù)字位數(shù)的值,對整數(shù)進行排序的算法,本文主要介紹了JS實現(xiàn)基數(shù)排序的示例代碼,具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • JavaScript運動框架 鏈式運動到完美運動(五)

    JavaScript運動框架 鏈式運動到完美運動(五)

    這篇文章主要為大家詳細介紹了JavaScript運動框架的第五部分,鏈式運動到完美運動,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • 詳解JavaScript樹結構

    詳解JavaScript樹結構

    對于數(shù)據(jù)結構“樹”,想必大家都熟悉,本文,我們就再來回顧一下數(shù)據(jù)結構中的二叉樹與樹,并用JavaScript實現(xiàn)它們。下面就跟著小編一起來看下吧
    2017-01-01
  • Javascript+CSS實現(xiàn)影像卷簾效果思路及代碼

    Javascript+CSS實現(xiàn)影像卷簾效果思路及代碼

    Arcmap里面的一個卷簾效果肯定記憶很深刻,我也對這種比較炫的卷簾效果做了一下研究,現(xiàn)在給大家匯報下結果
    2014-10-10
  • 詳解JavaScript中.splice()的用法

    詳解JavaScript中.splice()的用法

    Array.prototype.splice()是JavaScript中用于在數(shù)組的指定位置添加或刪除元素的方法,同時直接修改原數(shù)組,本文就來詳細的介紹一下.splice()的用法小結,感興趣的可以了解一下
    2025-10-10
  • Knockoutjs 學習系列(二)花式捆綁

    Knockoutjs 學習系列(二)花式捆綁

    這篇文章主要介紹了Knockoutjs 學習系列(二)花式捆綁 的相關資料,主要介紹了knockoutjs中各種綁定的使用方法,非常不錯具有參考借鑒價值,需要的朋友可以參考下
    2016-06-06

最新評論

常德市| 自贡市| 五家渠市| 元阳县| 当涂县| 罗田县| 临桂县| 自贡市| 永宁县| 姚安县| 双柏县| 海丰县| 房产| 宜春市| 公主岭市| 游戏| 共和县| 潮安县| 甘谷县| 普兰县| 丁青县| 昭平县| 共和县| 固安县| 佳木斯市| 和静县| 治县。| 时尚| 蓬安县| 白朗县| 濮阳县| 虞城县| 紫阳县| 阿拉善盟| 茂名市| 进贤县| 盐城市| 壶关县| 阳新县| 东平县| 元氏县|