您好,登錄后才能下訂單哦!
本篇內容主要講解“JS的運行機制原理是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“JS的運行機制原理是什么”吧!
代碼塊: JS中的代碼塊是指由<script>標簽分割的代碼段。JS是按照代碼塊來進行編譯和執(zhí)行的,代碼塊間相互獨立(即就算代碼塊1出錯,但不影響代碼塊2的加載和執(zhí)行),但變量和方法共享。
案例:2個代碼塊
<script type="text/javascript"> console.log("這是代碼塊一"); </script> <script type="text/javascript"> console.log ("這是代碼塊二"); </script>
HTML頁面中JS的加載原理: 在加載HTML頁面的時候,當瀏覽器遇到內嵌的JS代碼時會停止處理頁面,先執(zhí)行JS代碼,然后再繼續(xù)解析和渲染頁面。同樣的情況也發(fā)生在外鏈的JS文件中,瀏覽器必須先花時間下載外鏈文件中的代碼,然后解析并執(zhí)行它,在這個過程中,頁面的渲染和用戶互交完全被阻塞。由于現(xiàn)代瀏覽器都允許并行下載JS文件,因此<script>標簽在下載外部資源時不會阻塞其他的<script>標簽。遺憾的是JS下載過程仍然會阻塞其他資源的下載。
JavaScript的單線程:
JS語言的一大特點就是單線程,也就是說,同一個時間只能做一件事情。之所以是單線程,是因為與它的用途有關,作為瀏覽器腳本語言,JS的主要用途是與用戶互動以及操作DOM。這決定了它只能是單線程,否則會帶來復雜的同步問題。為了利用多核CPU的計算功能,HTML5提出了web worker標準,允許JS腳本創(chuàng)建多個線程,但是子線程完全受主線程控制,且不能操作DOM,所以這個新標準并沒有改變JS單線程的本質。
JavaScript的任務列隊:
JS任務可以分為兩種:一種是同步任務,另一種是異步任務。注意,只有主線程空了,才會去讀取"任務隊列",這就是JS的運行機制,這個過程會不斷重復。
同步任務:在主線程上排隊執(zhí)行的任務,只有前一個任務執(zhí)行完畢了,才會執(zhí)行后一個任務。
異步任務:在主線程之外,還存在一個“任務列隊”,異步任務就是不進入主線程,而是進入“任務列隊”的任務,只有“任務列隊”通知主線程,某個異步任務可以執(zhí)行了并且同步任務執(zhí)行完畢,該任務才會進入主線程執(zhí)行。
Javascript的事件和回調函數(shù):
"任務列隊"是一個事件的列隊,IO設備完成一項任務,就在"任務隊列"中添加一個事件,表示相關的異步任務可以進入"執(zhí)行棧"了。主線程讀取"任務隊列",就是讀取里面有哪些事件。"任務隊列"中的事件,除了IO設備的事件以外,還包括一些用戶產生的事件(如鼠標點擊、頁面滾動等等)。只要指定過回調函數(shù),這些事件發(fā)生時就會進入"任務隊列",等待主線程讀取。所謂"回調函數(shù)",就是那些會被主線程掛起的代碼。異步任務必須指定回調函數(shù),當主線程開始執(zhí)行異步任務,就是執(zhí)行對應的回調函數(shù)。"任務隊列"是個先進先出的數(shù)據(jù)結構,排在前面的事件,優(yōu)先被主線程讀取。主線程的讀取過程基本上是自動的,只要執(zhí)行棧一清空,"任務隊列"上***位的事件就自動進入主線程。但是,由于存在后文提到的"定時器"功能,主線程首先檢查一下執(zhí)行時間,某些事件只有到了規(guī)定的時間,才能返回主線程。
定時器:
除了放置異步任務的事件,"任務隊列"還可以放置定時事件,即指定某些代碼在多少時間之后執(zhí)行。定時器功能主要由setTimeout()和setInterval()這兩個函數(shù)來完成,它們的內部運行機制完全一樣,區(qū)別在于前者指定的代碼是一次性執(zhí)行,后者則為反復執(zhí)行。以下主要討論setTimeou()方法:
setTimeout()接受兩個參數(shù),***個是回調函數(shù),第二個是推遲執(zhí)行的毫秒數(shù)
console.log(1) setTimeout(function (){ console.log(2) }, 1000); console.log(3)
上面代碼的執(zhí)行結果是1=>3=>2,因為setTimeout()將第二行推遲到1000毫秒之后執(zhí)行
如果將setTimeout()的第二個參數(shù)設為0,就表示當前代碼執(zhí)行完(執(zhí)行棧清空)以后立即執(zhí)行
setTimeout(function (){ console.log(2) }, 0); console.log(3)
上面代碼的執(zhí)行結果是3=>2,因為只有在執(zhí)行完第二行以后,系統(tǒng)才會去執(zhí)行"任務隊列"中的回調函數(shù)??傊?,setTimeout(fn, 0)的含義是,指定某個任務在主線程最早的空閑時間執(zhí)行,也就是說盡可能早的執(zhí)行。它在"任務隊列"的尾部添加一個事件,因此要等到同步任務和"任務隊列"現(xiàn)有的事情都處理完,才會得到執(zhí)行。
需要注意的是,setTimeout()知識將事件插入了"任務隊列",必須等到當前代碼(執(zhí)行棧)執(zhí)行完,主線程才會去執(zhí)行它指定的回調函數(shù),要是當前代碼耗時很長,有可能要等很久,所以并沒有辦法保證回調函數(shù)一定會在setTimeout()指定的時間執(zhí)行。
到此,相信大家對“JS的運行機制原理是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續(xù)學習!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。