摘要:單線程定義單線程在程序執行時,所走的程序路徑按照連續順序排下來,前面的必須處理好,后面的才會執行。單線程就是進程只有一個線程。
單線程定義
單線程在程序執行時,所走的程序路徑按照連續順序排下來,前面的必須處理好,后面的才會執行。 單線程就是進程只有一個線程。 多線程就是進程有多個線程。Javascript 單線程
其實這里Javascript的單線程運行機制和上面單線程定義是一個執行流程,它只有一個主線任務,比如:前面有一條河中間只有一根木棍,想要過河只能從一邊按順序走,單個單個的執行,如果從兩頭一起過河Javascript的單線程就會造成阻塞,這里只是舉例了一個簡單的解釋示例,雖然JavaScript是單線程的且效率太低只能按部就班的一步步走,可是瀏覽器內部不是單線程的。你的一些I/O操作、定時器的計時和事件監聽(click, keydown...)等都是由瀏覽器提供的其他線程來完成的任務隊列和事件循環
調用棧
代碼在運行過程中,會有一個叫做調用棧的概念。調用棧是一種棧結構,它用來存儲計算機程序執行時候其活躍子程序的信息。(比如什么函數正在執行,什么函數正在被這個函數調用等等信息)
代碼示例
function expale(a) { return a+1 } console.log(expale(1))
上面的例子我們創建了一個簡單的函數,然后利用console打印并執行了這個函數,在console這里執行的時候已經形成了一個棧,我們也可以比喻成一個比較大的盒子,console.log(expale(1))就是底部的一個盒子,然后expale(1)會變成另一個盒子落在console.log(expale(1))上面這就形成了棧,其實就是上面所說到的存儲計算機程序執行時候其活躍子程序的信息。最后只想說因為它是單線程
任務隊列
宏任務隊列: setTimeout setInterval setImmediate I/O UI rendering (瀏覽器渲染) 微任務隊列: process.nextTick(下一個事件輪詢的時間點上執行) Promise Object.observer MutationObserver(監視 DOM 變動的接口) console.log("11221121"); // 微任務 Promise.resolve().then(() => { console.log("p 1"); }); // 宏任務 setTimeout(() => { console.log("setTimeout"); }, 0);
等宏任務執行完(全局執行完)就會開始執行整個微任務隊列
事件循環
如上圖所示stack存儲著要執行的任務,下面黃色的onclick函數就是消息隊列,一旦有異步響應就會被推入到該隊列中。比如:用戶的點擊事件,setTimeout等等,然后再進入到stack棧中,然后再有任務進入消息隊列,再執行這樣就形成了事件循環 單線程從任務隊列中讀取任務是不斷循環的,每次棧被清空后,都會在任務隊列中讀取新的任務,如果沒有新的任務,就會等待,直到有新的任務,這就叫任務循環。因為每個任務都由一個事件所觸發,所以也叫事件循環。異步機制
如果函數是異步的,發出調用之后,馬上返回,但是不會馬上返回預期結果。調用者不必主動等待,當被調用者得到結果之后會通過回調函數主動通知調用者,上面咱們也簡單的介紹了棧和任務隊列,以及簡單的事件循環,做了一些鋪墊
代碼
function send () { ajax()... } send()
上面是一段ajax的一段代碼執行,這時候單線程里面已經有這個任務了,當我們執行send()之后這個任務在頁面中其實已經完成了,但是我們無法拿到它的結果,在JavaScript中通過回調函數在耗時操作執行完成后把相應的結果信息傳遞給回調函數,通知執行JavaScript代碼的線程執行回調,這也就應上面那句話“不會馬上返回預期結果”
瀏覽器常駐線程渲染引擎線程:顧名思義,該線程負責頁面的渲染
JS引擎線程:負責JS的解析和執行
定時觸發器線程:處理定時事件,比如setTimeout, setInterval
事件觸發線程:處理DOM事件
異步http請求線程:處理http請求
在這里我們要注意js引擎和渲染線程是不能同時進行的,渲染要在js引擎之前
代碼setTimeout(function(){ console.log("timer a"); }, 0) for(var j = 0; j < 5; j++){ console.log(j); } setTimeout(function(){ console.log("timer b"); }, 0) console.log("click begin");
setTimeout的作用是操作者可以設定時間插隊,我們可以把它想象成一個會員,有特殊待遇,你可以插隊,但是這里的setTimeout(fn, 0)是將函數插入執行隊列,等待執行,但是它不會立即執行,不是立即執行,下面的代碼就是一個很好的例子 b a
setTimeout(function() { console.log("a") }, 0) console.log("b")
總結
其實JavaScript單線程并不孤單(瀏覽器的其他線程幫助它),它只是執行棧內的同步任務,執行完之后會再次執行下一個,直到執行完為止,然后棧中無任務事件,它就會等待直到它出現,一直這樣的循環下去
參考文章
JavaScript異步機制詳解
JavaScript單線程和異步機制
阮老師Event Loop
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/109873.html
摘要:的單線程,與它的用途有關。特點的顯著特點異步機制事件驅動。隊列的讀取輪詢線程,事件的消費者,的主角。它將不同的任務分配給不同的線程,形成一個事件循環,以異步的方式將任務的執行結果返回給引擎。 這兩天跟同事同事討論遇到的一個問題,js中的event loop,引出了chrome與node中運行具有setTimeout和Promise的程序時候執行結果不一樣的問題,從而引出了Nodejs的...
摘要:定時器機制更正之前的錯誤認識函數內調用,函數結束。在規定的時間之后,依然會觸發的回調。首先要確認幾點單線程瀏覽器多線程單線程原因如果多線程,那么刪除或者創建元素,都需要在線程之間通信。因為瀏覽器不確定是狀態。所以,設計之初就是單線程。 js定時器機制 更正之前的錯誤認識:1.函數內調用settimeout,函數結束。在規定的時間之后,依然會觸發settimeout的回調。 首先要確認j...
摘要:每個線程的任務執行順序都是先進先出在運行的環境中,有一個負責程序本身的運行,作為主線程另一個負責主線程與其他線程的通信,被稱為線程。主線程繼續執行我是第一主線程執行完畢,從線程讀取回調函數。 前言 上星期面試被問到了事件執行順序的問題,想起來之前看《深入淺出Node.js》時看到這一章就忽略了,這次來分析一下JavaScript的事件執行順序。廢話少說,正題開始。 單線程JavaScr...
摘要:深入理解引擎的執行機制靈魂三問為什么是單線程的為什么需要異步單線程又是如何實現異步的呢中的中的說說首先請牢記點是單線程語言的是的執行機制。 深入理解JS引擎的執行機制 1.靈魂三問 : JS為什么是單線程的? 為什么需要異步? 單線程又是如何實現異步的呢? 2.JS中的event loop(1) 3.JS中的event loop(2) 4.說說setTimeout 首先,請牢記2...
摘要:深入理解引擎的執行機制最近在反省,很多知識都是只會用,不理解底層的知識。在閱讀之前,請先記住兩點是單線程語言的是的執行機制。所以,是存在異步執行的,比如單線程是怎么實現異步的場景描述通過事件循環,所以說,理解了機制,也就理解了的執行機制啦。 深入理解js引擎的執行機制 最近在反省,很多知識都是只會用,不理解底層的知識。所以在開發過程中遇到一些奇怪的比較難解決的bug,在思考的時候就會收...
閱讀 737·2021-11-11 16:54
閱讀 3053·2021-09-26 09:55
閱讀 2002·2021-09-07 10:20
閱讀 1198·2019-08-30 10:58
閱讀 1039·2019-08-28 18:04
閱讀 698·2019-08-26 13:57
閱讀 3583·2019-08-26 13:45
閱讀 1150·2019-08-26 11:42