摘要:換個說法微任務優先于當前調用棧產生的宏任務被執行如果能理解下面這段代碼的執行過程應該就基本理解任務隊列的執行過程了輸出順序為,,,,,,
這篇文章是我自己的一個學習總結,并不是非常詳細,結合給出的鏈接可以有更細致的認識
先介紹幾個概念,便于理解
關于堆和棧(作為內存區域來說)堆(heap):存放object、array、function等不確定內存大小的數據存儲;
棧(stack):存放基本數據類型以及引用數據類型指向堆中的數據的指針,具有具體大小的數據結構,存取速度快;
調用棧(作為一種代碼運行機制)call stack(調用棧)指的是函數調用運行的機制,具體參考該鏈接:javascrip調用棧
事件循環機制(event loop)參考:js事件循環機制
存在整個javascript腳本執行期間
作用:將任務隊列的中可以執行的函數壓入調用棧中
任務隊列(task queue)任務隊列主要分為兩種:
宏任務(macro task):在新標準中叫task
宏任務主要包括:script(整體代碼), setTimeout, setInterval, setImmediate, I/O, UI rendering
微任務(micro task):在新標準中叫jobs
微任務主要包括:process.nextTick, Promise, Object.observe(已廢棄), MutationObserver(html5新特性)
以上提到的不只有瀏覽器方法,還有nodejs的方法,這里不具體說明了
執行特點:每當調用棧為空時,事件循環機制會將一個宏任務隊列中任務壓入調用棧中
以空的調用棧為起點的話,先執行所有宏任務,再執行所有微任務,然后調用棧又為空,這樣一次可以看作一個單元,之后就是一直在循環執行這樣單元
分解執行過程:
執行所有調用棧中的宏任務
宏任務執行過程中產生的微任務加入到微任務隊列
宏任務執行完立刻執行所有微任務隊列中的任務
以上執行完畢,檢查渲染,GUI線程接管渲染
渲染完畢后,js線程接管,開啟下一次事件循環(每一次事件循環(script不包括),只處理一個宏任務),執行下一次宏任務(任務隊列中取)
不好理解的地方:
以上過程(無論宏任務還是微任務執行)中產生的宏任務進入宏任務隊列等待,進入后面的循環執行,不在當次循環中被執行
但是以上過程中(包括微任務)產生的微任務又會被立刻放到當次循環的微任務隊列后面按順序執行
以上兩句可能有點繞,可以參考上面循環機制的鏈接,有相關圖解。
換個說法:微任務優先于當前調用棧產生的宏任務被執行
如果能理解下面這段代碼的執行過程應該就基本理解任務隊列的執行過程了:
setTimeout(() => { console.log("1") new Promise((resolve) => { resolve() }).then(() => { console.log("2") }) }, 0); setTimeout(() => { console.log("3") }, 0); new Promise((resolve) => { resolve() }).then(() => { console.log("4") new Promise((resolve) => { resolve() }).then(() => { console.log("5") }) setTimeout(() => { console.log("6") }, 0); }) new Promise((resolve) => { resolve() }).then(() => { console.log("7") }) // 輸出順序為: 4,7,5,1,2,3,6
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97486.html
摘要:從異步過程的角度看,函數就是異步過程的發起函數,事件監聽函數就是異步過程的回調函數。事件觸發時,表示異步任務完成,會將事件監聽器函數封裝成一條消息放到消息隊列中,等待主線程執行。 1.為什么JavaScript是單線程? JavaScript語言的一大特點就是單線程,也就是說,同一個時間只能做一件事。那么,為什么JavaScript不能有多個線程呢?這樣能提高效率啊。JavaScrip...
摘要:接下來處理微任務隊列,打印,后面一個不會有任何打印,但是會執行執行后面的代碼打印進入第二次事件循環,執行宏任務隊列打印 事件循環機制 理解js的事件循環機制,能夠很大程度的幫我們更深層次的理解平時遇到的一些很疑惑的問題 簡單版本 下面來看一段代碼,想想它的結果和你的結果是否一樣 setTimeout(function() { console.log(1) ...
摘要:異步請求線程在在連接后是通過瀏覽器新開一個線程請求將檢測到狀態變更時,如果設置有回調函數,異步線程就產生狀態變更事件,將這個回調再放入事件循環隊列中。 基礎:瀏覽器 -- 多進程,每個tab頁獨立一個瀏覽器渲染進程(瀏覽器內核) 每個瀏覽器渲染進程是多線程的,主要包括:GUI渲染線程 JS引擎線程 也稱為JS內核,負責處理Javascript腳本程序。(例如V8引擎) JS引擎線程負...
摘要:的單線程,與它的用途有關。只要指定過回調函數,這些事件發生時就會進入任務隊列,等待主線程讀取。四主線程從任務隊列中讀取事件,這個過程是循環不斷的,所以整個的這種運行機制又稱為事件循環。令人困惑的是,文檔中稱,指定的回調函數,總是排在前面。 原文:http://www.cnblogs.com/Master... 一、為什么JavaScript是單線程? JavaScript語言的一大特點...
摘要:而這些隊列由的事件循環來搞定宏任務與微任務,在最新標準中,它們被分別稱為與。我們梳理一下事件循環的執行機制循環首先從宏任務開始,遇到,生成執行上下文,開始進入執行棧,可執行代碼入棧,依次執行代碼,調用完成出棧。 寫在前面 js是一門單線程的編程語言,也就是說js在處理任務的時候,所有任務只能在一個線程上排隊被執行,那如果某一個任務耗時比較長呢?總不能等到它執行結束再去執行下一個。所以在...
閱讀 2975·2023-04-26 02:04
閱讀 1283·2021-11-04 16:07
閱讀 3707·2021-09-22 15:09
閱讀 682·2019-08-30 15:54
閱讀 1904·2019-08-29 14:11
閱讀 2529·2019-08-26 12:19
閱讀 2259·2019-08-26 12:00
閱讀 760·2019-08-26 10:27