js終止循環,js結束當前循環關鍵詞_干貨||什么是事件循環機制

 2023-12-06 阅读 22 评论 0

摘要:事件循環機制經常有小伙伴問到我什么是 js 的事件循環機制,這里我就簡單來給這些有困惑的小伙伴進行一下解答。我將從下面幾個方面來循序漸進的為大家來進行講解:區分進程和線程瀏覽器的多進程瀏覽器包含哪些進程js 事件循環機制宏任務與微任務區分進程和線程js

事件循環機制

經常有小伙伴問到我什么是 js 的事件循環機制,這里我就簡單來給這些有困惑的小伙伴進行一下解答。

我將從下面幾個方面來循序漸進的為大家來進行講解:

  • 區分進程和線程
  • 瀏覽器的多進程
  • 瀏覽器包含哪些進程
  • js 事件循環機制
  • 宏任務與微任務

區分進程和線程

js終止循環、在講解 js 事件循環機制之前,首先我們得說說進程與線程。兩者有什么區別呢?

這里做一個形象的比喻:

```js - 進程是一個工廠,工廠有它的獨立資源

  • 工廠之間相互獨立
  • 線程是工廠中的工人,多個工人協作完成任務
  • 工廠內有一個或多個工人
  • 工人之間共享空間 ```

下面我們再來完善一下這個概念:

js while循環,```js - 工廠的資源 -> 系統分配的內存(獨立的一塊內存)

  • 工廠之間的相互獨立 -> 進程之間相互獨立
  • 多個工人協作完成任務 -> 多個線程在進程中協作完成任務
  • 工廠內有一個或多個工人 -> 一個進程由一個或多個線程組成
  • 工人之間共享空間 -> 同一進程下的各個線程之間共享程序的內存空間(包括代碼段、數據集、堆等) ```

怎么樣?這個比喻很貼切吧,接下來我們再到電腦中實際的看一下進程。

舉個例子,如果你是 windows 操作系統的電腦,你可以打開任務管理器,在里面可以看到一個后臺進程列表。

這里列表中的每一項,就是一個進程。如下圖:

f1700e3b41faab1c53bc09566db13831.png

js?所以,這下子你應該理解了,所謂進程,就是 cpu 資源分配的最小單位(系統會給它分配內存)

如果用較為官方的術語來描述的話,那就是:

  • 進程是 cpu 資源分配的最小單位(是能擁有資源和獨立運行的最小單位)
  • 線程是 cpu 調度的最小單位(線程是建立在進程的基礎上的一次程序運行單位,一個進程中可以有多個線程)
注意: 1. 不同進程之間也可以通信,不過代價較大。 2. 現在,一般通用的叫法:單線程與多線程,都是指在一個進程內的單和多。所以核心還是得屬于一個進程才行。

瀏覽器是多進程的

到目前為止,你已經弄懂了進程與線程之間的區別。那么我們的瀏覽器在運行時也是會開啟一個進程么?

html for循環、打開 Google 瀏覽器,開啟多個標簽頁,然后打開任務管理器,如下圖:

683f2685a21ce0fedee42df45413287f.png

可以看到,這里一個標簽頁就是一個進程。所以可以這么講:

  • 瀏覽器是多進程的
  • 瀏覽器之所以能夠運行,是因為系統給它的進程分配了資源(cpu、內存)
  • 簡單點理解,每打開一個 Tab 頁,就相當于創建了一個獨立的瀏覽器進程。
注意:在這里瀏覽器應該也有自己的優化機制,有時候打開多個 tab 頁后,可以在 Chrome 任務管理器中看到,有些進程被合并了,所以每一個 Tab 標簽對應一個進程并不一定是絕對的。

瀏覽器包含哪些進程

上面已經說了,瀏覽器是多進程的,那么瀏覽器中具體包含哪些進程呢?

  • Browser 進程:瀏覽器的主進程(負責協調、主控),只有一個。作用有:
  • 負責瀏覽器界面顯示,與用戶交互。如前進,后退等
  • 負責各個頁面的管理,創建和銷毀其他進程
  • 將 Renderer 進程得到的內存中的 Bitmap,繪制到用戶界面上
  • 網絡資源的管理,下載等
  • 第三方插件進程:每種類型的插件對應一個進程,僅當使用該插件時才創建
  • GPU 進程:最多一個,用于 3D 繪制等
  • 瀏覽器渲染進程(瀏覽器內核)(Renderer 進程,內部是多線程的):默認每個 Tab 頁面一個進程,互不影響。主要作用為:
  • 頁面渲染,腳本執行,事件處理等
  • 強化記憶:在瀏覽器中打開一個網頁相當于新起了一個進程(進程內有自己的多線程)

js循環事件?這里,我們主要來看一下瀏覽器渲染進程(也被稱之為瀏覽器內核)。

上面有提到,每當我們開啟一個新的 Tab 頁時,就新啟一個進程。而進程里面又有自己的多線程。大致有哪些線程呢?這里列舉一些主要常駐線程如下:

  • GUI 渲染線程:負責渲染瀏覽器界面
  • js 引擎線程:負責處理 js 腳本程序
  • 事件觸發線程:歸屬于瀏覽器而不是 js 引擎,用來控制事件循環(可以理解,js 引擎自己都忙不過來,需要瀏覽器另開線程協助)
  • 定時觸發器線程:傳說中的 setInterval 與 setTimeout 所在線程
  • 異步 http 請求線程:在 XMLHttpRequest 連接后通過瀏覽器新開一個線程請求

js 事件循環機制

在有了上面的知識進行鋪墊以后,我們總算可以來講解一下 js 的事件循環機制了。

我們知道,在 js 中任務會分為同步任務和異步任務。

如果是同步任務,則會在主線程(也就是 js 引擎線程)上進行執行,形成一個執行棧。

但是一旦遇到異步任務,則會將這些異步任務交給異步模塊去處理,然后主線程繼續執行后面的同步代碼。

注:異步模塊的處理功能,是由運行環境提供的,擁有和 js 引擎互不干擾的線程。

當異步任務有了運行結果以后,就會在任務隊列里面放置一個事件,這個任務隊列由事件觸發線程來進行管理。

一旦執行棧中所有的同步任務執行完畢,就代表著當前的主線程(js 引擎線程)空閑了,系統就會讀取任務隊列,將可以運行的異步任務添加到執行棧中,開始執行。

如下圖所示:

83ba3d873161cd08902c111112366ee3.png

宏任務與微任務

在上文中,我們已經將 js 的事件循環機制梳理了一遍。

但是在上面的示意圖中,出現了宏任務與微任務的字樣,這究竟又是什么呢?

在 js 中,任務可以被分為 2 種類型:

宏任務(macrotask)與微任務(microtask)

宏任務可以理解為每次執行棧所執行的代碼就是一個宏任務,包括每次從事件隊列中獲取一個事件回調并放到執行棧中所執行的任務。

微任務可以理解為當前宏任務執行結束后立即執行的任務。

來看一個具體的例子:

```js console.log('script start');

setTimeout(function() { console.log('setTimeout'); }, 0);

Promise.resolve().then(function() { console.log('promise1'); }).then(function() { console.log('promise2'); });

console.log('script end'); ```

該代碼最終執行出來的結果為:

js script start script end promise1 promise2 setTimeout

原因很簡單,首先會執行同步的任務,輸出 script start 以及 script end,接下來由于 promise 是微任務,所以會在此次宏任務結束后立即輸出,而 setTimeout 由于是一個宏任務,所以會在上一次宏任務結束后,微任務結束后再執行。

來看一張下面的示意圖:

12fbd3ec230cca28199dc61d5a3856aa.png

最后,我們來總結一下:

  1. 首先,js 引擎會執行一個宏任務(如果當前的執行棧中沒有就會從事件隊列中去獲取)。
  2. 執行過程中如果遇到了微任務,就會將它添加到微任務的任務隊列中。
  3. 宏任務執行完畢之后,會立即執行當前微任務隊列中的所有微任務(依次執行)
  4. 至此,整個當前任務算是執行完畢了,開始檢查渲染,然后 GUI 線程進行接管,開始渲染瀏覽器頁面
  5. 渲染完畢之后,主線程(js 線程)繼續接管,然后開始下一個宏任務

以上就是今天的分享啦~

如果大家有問題或者想了解更多的

技術干貨可以私信發送【微信】加朗妹兒微信喲~

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/2/187233.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息