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

JavaScript事件循環(huán)機制的深入理解

 更新時間:2025年10月20日 11:07:55   作者:flower_tomb  
JavaScript是一種單線程語言,依賴于事件循環(huán)機制,完成對同步和異步任務的處理,從而實現(xiàn)非阻塞并發(fā),這篇文章主要介紹了JavaScript事件循環(huán)機制的相關資料,需要的朋友可以參考下

首先,我們要理解JavaScript是一門單線程的語言。所謂單線程,簡單來說一個時間只能做一件事,只有做完這件事,才能進行下一件。那為什么選擇單線程,不選擇多線程呢?這是由JS的用途決定的,JS的用途是與用戶交互,以及操作DOM,假設JS有兩個線程,一個要在某個DOM節(jié)點上添加內容,一個要刪除這個節(jié)點,那瀏覽器該以哪個為準呢,事情就變得復雜了。因此,JS在誕生時就是單線程,以后也不會改變。

這個時候就出現(xiàn)了問題,如果一件任務耗時太長,就會阻塞后面的任務。這樣肯定是不行的,所以,JS設計者將任務分成同步任務和異步任務。

同步任務就是在主線程(調用棧 Call Stack)中按照書寫順序依次執(zhí)行的任務。異步任務就是不阻塞主線程,而是交由其他線程或系統(tǒng)處理(如瀏覽器 或 Node.js ),處理完畢后,將其回調函數推入任務隊列。等到主線程空了,任務隊列中的任務再根據FIFO算法被調度到主線程中執(zhí)行。

事件循環(huán)的工作流程如下:

1.執(zhí)行調用棧中的所有同步代碼,直到??铡!緱J呛筮M先出結構,但是同步代碼入棧后直接執(zhí)行,執(zhí)行完畢彈出,所以順序還是不變的,但如果函數嵌套,則調用??赡艽嬖诙鄬雍瘮瞪舷挛?,最后進入的上下文最先執(zhí)行完,所以最先彈出】
2.檢查任務隊列,依次將任務調度到調用棧中執(zhí)行,直到隊列空。
3.重復循環(huán)。

只要調用棧空了,就去任務隊列中讀取任務,【用戶點擊按鈕觸發(fā)函數,函數就會被推入調用棧執(zhí)行】這個過程不斷重復循環(huán),這就是JavaScript的運行機制, 這種機制就叫做事件循環(huán)機制

所以有一個小細節(jié)就是setTimeout(callback,s)的真正含義并不是在指定的毫秒數后調用函數,而是最快s毫秒后調用函數,因為它需要等待主線程空后再被調用。

但是這里面還有更細節(jié)的問題,在事件循環(huán)的早期設計中,所有異步任務都進入同一個任務隊列。但隨著前端復雜度提升,任務優(yōu)先級問題顯露出來:

緊急任務需要優(yōu)先處理(如 Promise 狀態(tài)更新)
非緊急任務可以延后(如 UI 渲染前的計算)

因此,現(xiàn)代事件循環(huán)又將異步任務細分為兩類:

同步任務與宏任務:整個腳本(主線程代碼),即script標簽里的代碼,本身就是一個宏任務,主線程執(zhí)行腳本中的同步代碼屬于初始宏任務。整個腳本的執(zhí)行是第一個宏任務,同步代碼是它的組成部分。

于是,事件循環(huán)的工作流程就變成:

1.按照代碼書寫順序執(zhí)行初始宏任務:

如果遇到同步代碼,直接推入調用棧執(zhí)行。
如果遇到宏任務,將回調函數推入宏任務隊列。
如果遇到微任務,將回調函數推入微任務隊列。

2.清空微任務隊列:

當前宏任務執(zhí)行完畢后,依次將微任務隊列中的所有微任務推入調用棧執(zhí)行,直到微任務隊列清空。
注意:若微任務中又生成新的微任務,新微任務也會在此階段被立即執(zhí)行。

3.渲染更新(如有必要):

瀏覽器判斷是否需要渲染(通常根據屏幕刷新率,如 60Hz 對應約 16.6ms/次)。

4.開啟下一輪事件循環(huán):

從宏任務隊列中取出下一個宏任務執(zhí)行,重復上述流程。

Tips:我的一些思路歷程

剛開始我以為js在遇到settimeout這種定時器時,會將整個定時器函數推到宏任務隊列中,但其實不是的,
【如果是這樣的話,那一個3秒的宏任務,會和一個耗費8秒的微任務幾乎同時分別推入宏任務隊列和微任務隊列,那這個時候如果調用棧執(zhí)行空了,先取出這個微任務執(zhí)行,那可能8s的打印出來了,定時器還沒打印出來,這個深究的話這個理解是錯誤的,不過可以幫我記住任務隊列里放的都是處理過的回調

js遇到定時器之后,將定時器以及回調交給瀏覽器,由瀏覽器的定時模塊發(fā)起定時,處理完畢后(例如三秒后)將回調函數推入宏任務隊列。

接著列舉一些宏任務和微任務的理解,以及他們是怎么分類的

宏任務:

由宿主環(huán)境發(fā)起,比如瀏覽器或者Node。js遇到這些任務時會向對應的環(huán)境發(fā)起請求,由瀏覽器或者node進行處理,處理完畢后推入宏任務隊列

‌瀏覽器環(huán)境‌: setTimeout、setInterval【定時器觸發(fā)線程】、DOM事件【事件觸發(fā)線程、GUI渲染線程】、AJAX回調【瀏覽器網絡線程】等需要瀏覽器線程協(xié)作的任務
‌Node環(huán)境‌: I/O操作、setImmediate等系統(tǒng)級異步操作

微任務:

由JavaScript引擎自身發(fā)起和管理【相當于是一種js本身的異步機制】,例如js遇到promise的時候,會執(zhí)行promise的同步部分,然后將promise的狀態(tài)標記為pending,而直到當resolve/reject被調用時,js才會將對應的.then或者.catch回調函數推入微任務隊列

‌語言級實現(xiàn)‌:Promise.then/catch/finally、queueMicrotask等屬于ECMAScript規(guī)范定義的異步機制

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

相關文章

最新評論

德昌县| 屏山县| 措勤县| 桃源县| 平昌县| 开远市| 合川市| 奇台县| 武山县| 大安市| 广宗县| 洛川县| 房产| 陵水| 新巴尔虎左旗| 和龙市| 枣强县| 辽宁省| 大丰市| 淮阳县| 抚宁县| 广安市| 乐平市| 南平市| 普格县| 湖南省| 延长县| 驻马店市| 通榆县| 安达市| 怀宁县| 甘洛县| 册亨县| 台山市| 景德镇市| 思茅市| 万山特区| 新龙县| 鱼台县| 开平市| 镇雄县|