91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎樣掌握JavaScript執行機制

發布時間:2022-01-21 09:34:54 來源:億速云 閱讀:139 作者:kk 欄目:web開發

本篇文章為大家展示了怎樣掌握JavaScript執行機制,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

一、為什么JavaScript是單線程

如果想了解JavaScript為什么是單線程的,我們就要從JavaScript是用來做什么工作的來入手。

JavaScript作為瀏覽器的腳本語言,產出的目的就是為了瀏覽器與用戶進行交互,操作DOM元素,從而提升用戶的交互及體驗感。JavaScript要操作瀏覽器的DOM元素,因此導致JavaScript無法成為多線程語言,我們假設一個場景,如果JavaScript是多線程語言,兩個線程同時操作一個DOM元素,一個線程需要編輯更新DOM元素,而另一個則是刪除DOM元素節點,這是瀏覽器應該以哪個為準呢?

同一時間只能做同一件事情,因為操作DOM元素的原因,導致單線程是JavaScript這門語言的核心,也是這門語言特點。

HTML5提出Web Worker標準,允許JavaScript腳本創建多個線程,但是子線程完全受主線程控制,且不得操作DOM。即使這樣的改動也并沒有改變js單線程的本質。

二、JavaScript中的同步與異步

javaScript的單線程機制,就導致同一時間只能做一件事情。就像一堆人在ATM取款機取款,即使后面再多的人在著急,也只能一個一個的排隊,等待前一個人取完款,才能輪到后一人。

可是這樣會導致如果說前一個任務消耗時間過長,后一個任務就會等待非常久,比如,我們需要加載一個數據量非常大的Ajax請求,我們不得不等待請求相應結果,再繼續往下行執后續任務。

那我們該如何處理這種情況呢?既然我們無法改變JavaScript的單線程機制,我們是否可以將一些耗時久的任務進行暫時掛起,等到主任務執行完成之后,再將這些掛載的任務執行。JavaScript的作者也想到了這樣的方式,JavaScript擁有了同步任務與異步任務。

同步任務就是,任務在主線程上進行排隊,下一個任務必須等待上一個任務執行完成,才可以執行。而異步任務是指,任務不進入主線程,而進入任務隊列(task queue)進行等待,進入任務隊列的任務只有"任務隊列"通知主線程,某個異步任務可以執行了,該任務才會進入主線程執行。

三、Event Loop事件循環機制

JavaScript的所有同步任務都在主線程上執行,形成一個執行棧。

任務隊列是先進先出的原則,先進隊列的事件先執行,后進隊列的事件后執行。

Event Loop

  • 執行執行棧中的同步任務。

  • 當遇到一個異步任務后不會一直等待其返回結果,會先將異步任務進行暫時掛起,繼續執行其他的同步任務。

  • 當異步任務有結果之后,JavaScript會任務將添加進任務隊列中。被添加進任務隊列中的任務不會立刻進行回調執行而是等待主線程(執行棧)空閑時才加入到執行棧中進行回調執行

  • 等待執行棧中的任務執行完畢。

  • 將任務隊列中的任務加入執行棧后執行。

如此反復,這樣就形成了一個無限的循環(event loop)。(下圖來自網絡)

怎樣掌握JavaScript執行機制

學習了 Event Loop 我們一起來看看下面這道題:

setTimeout(function(){
     console.log('setTimeout start')
 });
 new Promise(function(resolve){
     console.log('promise start');
     resolve()
 }).then(function(){
     console.log('promise then')
 });
 console.log('script end');

嘗試按照,上文我們剛學到的JavaScript執行機制去分析

1. 首先執行同步任務,執行到setTimeout,但是setTimeout是異步任務的暫時掛起,等待計時超時,添加進任務隊列中。

2. 繼續往下,在執行到new Promise,new Promise里面的是同步任務,打印 "promise start"。

3. 在執行到resolve將.then添加進任務隊列中。

4. 在執行 console.log('script end');打印"script end"。

5. 這時主任務都已經執行完成,在將異步任務添加進主任務中直接執行,打印"setTimeout start",再將.then添加進主任務中,打印"promise then"。

所以結果應該是:promise start -> script end -> setTimeout start -> promise then 嗎?

親自在瀏覽器執行后,結果居然不是這樣,而是 promise start -> script end -> promise then -> setTimeout start

宏任務與微任務

那為什么上文中的結果為什么跟我們預想的不一致,為什么 setTimeout start 會在 promise 之后打印。

其實是因為異步的執行也是有先后順序的。其實用異步跟同步的方式去劃分任務隊列的執行順序是不準確的。應該劃分為 微任務 與 宏任務。

  • 宏任務(macro-task):script 代碼、setTimeout、setInterval

  • 微任務(micro-task):Promise、process.nextTick

所以說setTimeout是異步任務中的 宏任務 ,而Promise是異步任務中的 微任務 。不管是 微任務 還是 宏任務,都會進入相應的 Event Queue, 接下來我們在看一個流程圖。

怎樣掌握JavaScript執行機制

我們來稍微理解一下:

  • 1. 執行宏任務(script代碼)

  • 2. 當執行宏任務的時遇到了微任務,就會將微任務添加進 Event Queue

  • 3. 在當前宏任務執行完成后,會查看微任務的 Event Queue ,并將里面全部的微任務依次執行完

  • 4. 在執行玩所有的為微任務之后,繼續進行第一步,以此循環

這便也是 javaScript 的運行機制,結合這個我們再重新的分析一下上面的例子。

  • 1. 首先執宏任務(script代碼 ),遇到setTimeout將其添加進宏任務的Event Queue。

  • 2. 繼續往下,在執行到new Promise,打印 "promise start"。

  • 3. 在執行到resolve,.then是微任務,添加進微任務的Event Queue。

  • 4. 在執行 console.log('script end');打印 "script end"。

  • 5. 到這里本輪的宏任務就已經全部執行結束了,這時查找微任務的 Eevent Queue 是否存在可執行的微任務, 發現有剛才在第三步添加進去額度.then,執行并打印 "promise then"

  • 6. 這時第一輪的 event loop 就已經徹底結束了,下一輪 event loop 先執行一個宏任務,發現宏任務的Event Queue中有添加進去的setTimeout,執行并打印 "setTimeout start"

永遠記住JavaScript是單線程,以前是、現在是、將來也會是。所有的多線程說法都是扯淡。

即使是Event Queue,也只不是實現異步的方式,也是js的執行機制。

以后能用JavaScript實現的。都將會用JavaScript來實現。

JavaScript是什么

JS是JavaScript的簡稱,它是一種直譯式的腳本語言,其解釋器被稱為JavaScript引擎,是瀏覽器的一部分,主要用于web的開發,可以給網站添加各種各樣的動態效果,讓網頁更加美觀。

上述內容就是怎樣掌握JavaScript執行機制,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

扶绥县| 谢通门县| 延安市| 明光市| 桂林市| 大埔县| 云南省| 墨竹工卡县| 祁东县| 西昌市| 仙居县| 台北县| 纳雍县| 彩票| 封开县| 缙云县| 临夏县| 莱西市| 新营市| 滨州市| 白朗县| 高碑店市| 新安县| 称多县| 井陉县| 芜湖县| 中牟县| 安徽省| 海门市| 会昌县| 彭泽县| 黑山县| 芦溪县| 玛沁县| 广汉市| 当涂县| 富宁县| 耒阳市| 卓资县| 思茅市| 江山市|