中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

如何理解JS的同步異步編程和EventLoop底層機制

發布時間:2021-10-15 13:51:26 來源:億速云 閱讀:157 作者:iii 欄目:web開發

這篇文章主要講解了“如何理解JS的同步異步編程和EventLoop底層機制”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“如何理解JS的同步異步編程和EventLoop底層機制”吧!

1?JS是單線程的,怎么達到異步編程:

1)JS是單線程的,大部分代碼都是同步編程。

2)JS中利用瀏覽器的多線程機制,基于單線程的EventLoop(事件循環機制)實現出異步的效果。

2?event loop (微任務與宏任務):

1)微任務 (microtask):優先級高,并且可以插隊,不是先定義先執行。包括:promise.then,async/await  [generator],requestAnimationFrame,observer,MutationObserver,setImmediate。

2)宏任務  (macrotask):優先級低,先定義的先執行。包括:ajax,setTimeout,setInterval,事件綁定,postMessage,MessageChannel(用于消息通訊)。

3?根據事件循環機制,重新梳理一下流程:

+先找微任務隊列,如果微任務隊列中有,先從微任務隊列中,一般按照存放順序獲取并且去執行。

+如果微任務隊列中沒有,則再去宏任務隊列中查找,在宏任務隊列中,一般是按照誰先到達執行的條件,就先把誰拿出來執行。

常考面試題:EventLoop事件循環

? 面試題1:

console.log('1') // 1  async function async1() {   console.log('2') // 2   await setTimeout(() => {     console.log('3') // 8   }, 0)   console.log('4') // 5 }  setTimeout(() => {   console.log('5') // 7 }, 0)  async1()  new Promise(function (resolve) {   console.log('6') // 3   resolve() }).then(function () {   console.log('7') // 6 })  console.log('8') // 4 // 結果:1 2 6 8 4 7 5 3

? 面試題2:

async function async1() {     console.log('async1 start'); // 2     await async2();     console.log('async1 end'); // 6 } async function async2() {     console.log('async2'); // 3 } console.log('script start'); // 1 setTimeout(function () {     console.log('setTimeout'); // 8 }, 0) async1(); new Promise(function (resolve) {     console.log('promise1'); // 4     resolve(); }).then(function () {     console.log('promise2'); // 7 }); console.log('script end'); // 5 //結果: script start async1 start async2 promise1 script end async1 end promise2 setTimeout

? 面試題3:

console.log(1); // 1 setTimeout(() => {   console.log(2); // 6   Promise.resolve().then(data => {      console.log(3); // 7   }); }); new Promise((resolve) => {   resolve()   console.log(4) // 2 }).then(() => {   console.log(5); // 4   setTimeout(() => {     console.log(6); // 8   }); }).then(() => console.log(7)) // 5 console.log(8); // 3  // 結果:1, 4, 8, 5, 7, 2, 3, 6 1, 4, 8 是同步  5, 7  是微任務  2 宏任務 3 微任務  6 宏任務

進程/線程

* 核心答案 | 基礎知識要夯實

1) 進程代表的是一個程序(瀏覽器開一個頁卡 (Tab頁) 就是一個進程);

2) 線程是用來處理處理進程中的具體事物的,如果一個程序中需要同時做好多事情,就需要開辟好多線程;

3) 一個線程同時只能做一件事情;

  • 官方的說法

  • 1) 進程是cpu資源分配的最小單位(是能擁有資源和獨立運行的最小單位)。

  • 2) 線程是cpu調度的最小單位(線程是建立在進程的基礎上的一次程序運行單位,一個進程中可以有多個線程)。

瀏覽器是多線程的

* 核心答案 | 基礎知識要夯實

1) 瀏覽器是多進程的;

2) 瀏覽器之所以能夠運行,是因為系統給它的進程分配了資源(cpu、內存);

3) 簡單點理解,每打開一個Tab頁,就相當于創建了一個獨立的瀏覽器進程;

如何理解JS的同步異步編程和EventLoop底層機制

那么接下來看看它都包含了哪些線程(列舉一些主要常駐線程)

GUI渲染線程

1) 負責渲染瀏覽器界面,解析HTML,CSS,構建DOM樹和RenderObject樹,布局和繪制等。

2) 當界面需要重繪(Repaint)或由于某種操作引發回流(reflow)時,該線程就會執行。

3)  注意,GUI渲染線程與JS引擎線程是互斥的,當JS引擎執行時GUI線程會被掛起(相當于被凍結了),GUI更新會被保存在一個隊列中等到JS引擎空閑時立即被執行。

JS引擎線程

也稱為JS內核,負責處理Javascript腳本程序。(例如V8引擎)

1) JS引擎線程負責解析Javascript腳本,運行代碼。

2) JS引擎一直等待著任務隊列中任務的到來,然后加以處理,一個Tab頁(renderer進程)中無論什么時候都只有一個JS線程在運行JS程序。

3) 同樣注意,GUI渲染線程與JS引擎線程是互斥的,所以如果JS執行的時間過長,這樣就會造成頁面的渲染不連貫,導致頁面渲染加載阻塞。

JS中的單線程異步編程

* 核心答案 | 基礎知識要夯實

JS是單線程的:瀏覽器只分配一個線程用來渲染JS代碼。

1、JS中的代碼大部分都是“同步編程”:上面的任務沒有處理完成,下面的任務是無法處理的。

2?但是JS中利用瀏覽器的多線程機制,可以規劃出“異步編程”效果。

  • 定時器

  • ajax/Fetch/跨域 (HTTP網絡請求)

  • 事件綁定

  • Promise中有也有異步編程

  • Generator / yield

  • async / await

計算程序執行的時間(預估)

1)運行監控 console.time/timeEnd(受當前電腦運行環境的影響)

2)大O表示法(提前預估)

console.time('AAA');  for (let i = 0; i < 99999999; i++) {}  console.timeEnd('AAA');

真實項目中應該避免死循環 (重要)

while (true) {} console.log('OK'); // 不執行:上述的死循環一直占用這“JS渲染線程”,線程空閑不下來,就處理不了其他的事情

定時器的異步編程

1)設置定時器任務是同步的

2)“間隔interval這么長時間,執行定時器綁定的函數” 這個任務是異步的

3)遇到異步任務,瀏覽器不會等待它執行完,則繼續渲染下面的代碼;當等到下面代碼運行完,時間也到達了執行的條件,才會把異步任務執行;

setTimeout(() => {     console.log("OK"); //2 }, 1000); console.log('NO'); //1

interval設置為零也不是立即執行,而是瀏覽器都有“最快反應時間(谷歌:5~6ms  IE:13~17ms)”,設置為零,最快也需要等到5~6ms左右

setTimeout(() => {     console.log('OK'); //2 }, 0); console.log('NO'); //1

? 異步編程例子一:

setTimeout(() => {     console.log(1); }, 20); console.log(2); setTimeout(() => {     console.log(3); }, 10); console.log(4); console.time('AA'); for (let i = 0; i < 90000000; i++) {     // do soming } console.timeEnd('AA'); //=>AA: 79ms 左右 console.log(5); setTimeout(() => {     console.log(6); }, 8); console.log(7); setTimeout(() => {     console.log(8); }, 15); console.log(9); // 結果:2,4,5,7,9,3,1,6,8

畫圖分析:( 有圖有真相 )

如何理解JS的同步異步編程和EventLoop底層機制

執行順序:同步任務 &mdash;> 微任務 &mdash;> 宏任務 (微任務、宏任務在EventQueue)

  • 細節點

  • 當棧中的“同步任務”或者其它任務沒有執行完之前,JS渲染線程不會空閑下來,些時哪怕定時器已經到達指定時間,也不會執行的。  “JS是單線程的,一次只能做一件事情” =>  定時器設定的等待時間是最快觸發執行的時間,很多時候,到時間不一定會執行,只有JS渲染線程空閑下來才會執行。

感謝各位的閱讀,以上就是“如何理解JS的同步異步編程和EventLoop底層機制”的內容了,經過本文的學習后,相信大家對如何理解JS的同步異步編程和EventLoop底層機制這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

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

AI

奉新县| 台南市| 黄冈市| 张掖市| 新田县| 永州市| 都安| 卫辉市| 教育| 金乡县| 高碑店市| 渑池县| 江西省| 芒康县| 临汾市| 枝江市| 沁源县| 清苑县| 原平市| 普兰店市| 象山县| 吉水县| 广昌县| 明水县| 定州市| 绥芬河市| 冀州市| 广东省| 大渡口区| 伊宁县| 安顺市| 佛坪县| 米林县| 兴国县| 和田县| 新邵县| 乌鲁木齐市| 石家庄市| 镇坪县| 苏尼特左旗| 西盟|