溫馨提示×

溫馨提示×

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

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

JS的執(zhí)行機(jī)制是什么意思

發(fā)布時(shí)間:2021-07-10 16:11:25 來源:億速云 閱讀:154 作者:chen 欄目:編程語言

本篇內(nèi)容主要講解“JS的執(zhí)行機(jī)制是什么意思”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“JS的執(zhí)行機(jī)制是什么意思”吧!

前言

JavaScript是一門單線程的非阻塞腳本語言,同一時(shí)刻只允許一個(gè)代碼段執(zhí)行。在單線程的機(jī)制下,執(zhí)行異步任務(wù)時(shí),在等待結(jié)果返回的這個(gè)時(shí)間段,后面的代碼就無法執(zhí)行了。

JS在執(zhí)行代碼時(shí),遇到異步任務(wù)之后還有同步任務(wù)的場景時(shí),它并不會(huì)等待異步任務(wù)執(zhí)行完,而是先執(zhí)行同步任務(wù),那么JS是如何做到這一點(diǎn)的呢?

本篇文章將詳細(xì)講解上述問題,歡迎各位感興趣的開發(fā)者閱讀本文。

事件循環(huán)

單線程

講事件循環(huán)之前,我們先來理解下為什么JS不設(shè)計(jì)成多線程的。

我們做個(gè)假設(shè),如果JS是多線程的,因?yàn)镴S有DOM API可以操作DOM,此時(shí)如果有兩個(gè)線程在操作同一個(gè)DOM,線程1刪除了這個(gè)dom節(jié)點(diǎn),線程2要操作這個(gè)dom,就會(huì)產(chǎn)生矛盾,到底以哪個(gè)線程為主。

為了避免這種情況的出現(xiàn),JS就被設(shè)計(jì)成了單線程 。 

宏任務(wù)與微任務(wù)

JS引擎把所有任務(wù)分為兩類:宏任務(wù)、微任務(wù)。

宏任務(wù)有:

  • script整體代碼
  • setTimeout、setInterval
  • I/O
  • UI渲染
  • postMessage
  • MessageChannel
  • requestAnimationFrame
  • setImmediate(Node.js 環(huán)境)

微任務(wù)有:

  • new Promise.then()
  • MutaionObserver
  • process.nextTick(Node.js 環(huán)境)

執(zhí)行規(guī)則

文章一開頭我們了解到了單線程的弊端,JS是通過事件循環(huán)機(jī)制(EventLoop)來解決這一弊端的,接下來我們來看下EventLoop的執(zhí)行規(guī)則:

  • 所有代碼作為宏任務(wù)進(jìn)入主線程執(zhí)行棧,開始執(zhí)行
  • 執(zhí)行過程中,同步代碼會(huì)立即執(zhí)行,宏任務(wù)進(jìn)入宏任務(wù)隊(duì)列,微任務(wù)進(jìn)入微任務(wù)隊(duì)列
  • 當(dāng)前宏任務(wù)執(zhí)行完成出隊(duì),讀取微任務(wù)隊(duì)列,有則執(zhí)行,直至全部執(zhí)行完畢
  • 執(zhí)行瀏覽器ui進(jìn)程渲染
  • 檢查是否有webworker任務(wù),有則執(zhí)行
  • 本輪宏任務(wù)執(zhí)行完成,回到第2步,繼續(xù)執(zhí)行,直至宏任務(wù)與微任務(wù)隊(duì)列全部清空

舉例說明

我們了解完它的執(zhí)行規(guī)則后,接下來我們舉個(gè)例子來說明下,如下所示:


console.log("1"); // 1 同步代碼:立即執(zhí)行 [1]

setTimeout(function() {
  console.log("2"); // 3 同步代碼執(zhí)行執(zhí)行 輸出2
  process.nextTick(function() {
    console.log("3"); // 4 進(jìn)入微任務(wù)隊(duì)列 [3]
  });
  new Promise(function(resolve) {
    console.log("4"); // 3 同步代碼執(zhí)行執(zhí)行 輸出4
    resolve();
  }).then(function() {
    console.log("5"); // 4 進(jìn)入微任務(wù)隊(duì)列 [3, 5]
  });
});

process.nextTick(function() {
  console.log("6"); // 2 進(jìn)入微任務(wù)隊(duì)列 [6]
});

new Promise(function(resolve) {
  console.log("7"); // 1 宏任務(wù):立即執(zhí)行 [1, 7]
  resolve();
}).then(function() {
  console.log("8"); // 2 進(jìn)入微任務(wù)隊(duì)列 [6, 8]
});

setTimeout(function() {
  console.log("9"); // 5 宏任務(wù):立即執(zhí)行 [9]
  process.nextTick(function() {
    console.log("10"); // 6 進(jìn)入微任務(wù)隊(duì)列 [10]
  });
  new Promise(function(resolve) {
    console.log("11"); // 5 宏任務(wù):立即執(zhí)行 [9, 11]
    resolve();
  }).then(function() {
    console.log("12"); // 6 進(jìn)入微任務(wù)隊(duì)列 [10, 12]
  });
});

// 執(zhí)行順序:1 7 6 8 2 4 3 5 9 11 10 12
 

process.nextTick()為node中的方法,你可以把它理解為與promise一樣的微任務(wù),promise的executor函數(shù)中的同步代碼會(huì)立即執(zhí)行。

我們來分析下上述代碼的執(zhí)行順序,如下圖所示:

JS的執(zhí)行機(jī)制是什么意思

運(yùn)行結(jié)果如下所示:

JS的執(zhí)行機(jī)制是什么意思

當(dāng)你把上述示例代碼啃透后,那么你也就理解js的事件循環(huán)機(jī)制了。

當(dāng)然,你可能沒有那么快就啃透這個(gè)例子,這種概念性的東西,掌握它最好的辦法就是:將示例代碼放到編輯器里,對照著事件循環(huán)的執(zhí)行規(guī)則,一行一行的去讀代碼,大腦過一遍,猜測運(yùn)行結(jié)果,然后再去執(zhí)行代碼判斷執(zhí)行結(jié)果是否與你猜的一致。

最后,舉一反三,去網(wǎng)上找一些事件循環(huán)的面試題多加練習(xí),慢慢的你就把這個(gè)知識點(diǎn)啃透了,Good Luck!

到此,相信大家對“JS的執(zhí)行機(jī)制是什么意思”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

js
AI