總結javascript基礎概念(二):事件隊列迴圈

来源:https://www.cnblogs.com/banyue/archive/2018/02/11/8442621.html
-Advertisement-
Play Games

主要問題:1、JS引擎是單線程,如何完成事件迴圈的?2、定時器函數為什麼計時不准確?3、回調與非同步,有什麼聯繫和不同?4、ES6的事件迴圈有什麼變化?Node中呢?5、非同步控制有什麼難點?有什麼解決方案? ...


主要問題:

  1、JS引擎是單線程,如何完成事件迴圈的?

  2、定時器函數為什麼計時不准確?

  3、回調與非同步,有什麼聯繫和不同?

  4、ES6的事件迴圈有什麼變化?Node中呢?

  5、非同步控制有什麼難點?有什麼解決方案?

 

二、事件隊列迴圈

(一)、瀏覽器線程

JavaScript引擎是基於事件驅動單線程運行的,瀏覽器無論在什麼時候都只且只有一個線程在運行JavaScript程式,等待著任務隊列中任務的到來,然後加以處理。

瀏覽器的內核是多線程的,它們在內核控制下相互配合協作,一個瀏覽器至少實現三個常駐線程:JavaScript引擎線程,GUI渲染線程,瀏覽器事件線程。

GUI渲染線程負責渲染瀏覽器界面,當界面需要重繪(Repaint)或由於某種操作引發迴流(Reflow)時,該線程就會執行。GUI渲染線程與JavaScript引擎是互斥的,當JavaScript引擎執行時GUI線程會被掛起,GUI更新會被保存在一個隊列中等到JavaScript引擎空閑時立即被執行。所以渲染操作的消耗特別大。

 

 

(二)、事件類型與隊列


事件迴圈:引擎會創建一個類似於 while (true) 的無限迴圈,每執行一次迴圈體的過程稱之為 Tick。每次 Tick 的過程就是查看是否有待處理事件,如果有則取出相關事件及回調函數放入執行棧中由主線程執行。待處理的事件會存儲在一個任務隊列中,也就是每次 Tick 會查看任務隊列中是否有需要執行的任務

任務隊列:非同步操作會將相關回調添加到任務隊列中。而不同的非同步操作添加到任務隊列的時機也不同,如 onclick, setTimeout, ajax 處理的方式都不同,這些非同步操作是由瀏覽器內核的 webcore 來執行的,webcore 包含上圖中的3種 webAPI,分別是 DOM Binding、network、timer模塊。

onclick 由瀏覽器內核的 DOM Binding 模塊來處理,當事件觸發的時候,回調函數會立即添加到任務隊列中。
setTimeout 會由瀏覽器內核的 timer 模塊來進行延時處理,當時間到達的時候,才會將回調函數添加到任務隊列中。

 

js定時器不准確的原因:

1、非同步函數的回調執行會阻塞下一個迴圈tick。2、瀏覽器的時間精度不一。

 

ajax 則會由瀏覽器內核的 network 模塊來處理,在網路請求完成返回之後,才將回調添加到任務隊列中。

 

主線程:JS 只有一個線程,稱之為主線程。而事件迴圈是主線程中執行棧里的代碼執行完畢之後,才開始執行的。所以,主線程中要執行的代碼時間過長,會阻塞事件迴圈的執行,也就會阻塞非同步操作的執行。只有當主線程中執行棧為空的時候(即同步代碼執行完後),才會進行事件迴圈來觀察要執行的事件回調,當事件迴圈檢測到任務隊列中有事件就取出相關回調放入執行棧中由主線程執行。

在這個過程提高頁面響應速度的方式:減少主線程同步代碼的數量,將不重要的代碼轉移到事件迴圈階段執行。

 

 (三)、ES6的任務隊列

對事件隊列進行了改造,使得非同步回調可以更早的執行,每個tick間隙都會優先執行任務隊列,不用排到事件隊列的末尾。一道必考題,看一下執行順序:

Promise實例具有三種狀態:等待,決議,拒絕。由此產生的非同步事件執行會作為任務隊列掛在當前tick迴圈的末尾執行。

 

(四)、Nodo中的事件迴圈
JS引擎的事件迴圈都需要宿主環境提供隊列維護,Node脫離了瀏覽器,用到了不同的方式和底層系統做交互。

觀察者:引擎在每個迴圈過程中詢問觀察者是否有要處理的事件。

在Window下,觀察者基於IOCP監聽事件的完成情況;在*nix下基於多線程創建。

在node增加了非同步執行的api,如process。nextTick()和setImmiediate。
process。nextTick()的回調函數保存在一個數組中,setImmiediate則是保存在一個鏈表中。
在每輪迴圈中,會將nextTick的數組中回調函數全部執行完,然後執行一個setImmiediate鏈表中的回調。

 

(五)、非同步事件的處理
非同步事件的處理過程中有執行時間、順序不確定,回調地獄,錯誤難捕獲定位等問題。

 

1、jQuery的 Deferred隊列模塊
  JQ在 Deferred隊列模塊的基礎上,模擬實現了promise相似的方法。可以做到鏈式回調,延遲訪問。
2、ES6 Promise
  promise實例決議後就不可更改,解決了信任問題。可以使用鏈式回調,隨時訪問非同步事件的狀態。相比之前要將回調交給另一方控制,promise可以將回調的執行控制在自己的邏輯中。至此仍未從實質上解決非同步。
3、Generator
  生成器函數實現了真正的非同步控制,可以切換執行環境,併在執行環境之間傳遞變數,實現協作的函數線程。
著名的co模塊,結合使用Promise和Generator實現了非同步流程的同步編碼形式。
4、async 函數
  ES2017 標準引入了 async 函數,使得非同步操作變得更加方便。就是 Generator 函數的語法糖。
Node框架Koa採用了最新的async處理非同步流程,使得編碼更加簡潔流暢。

 

推薦參考書:

  《深入淺出NodeJS》

  《jQuery技術內幕》

  《Webkit技術內幕》

  《你不知道的JavaScript》

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 當ScrollView鑲嵌listview會顯示不全,通過查看ScrollView測量高度的源碼,會發現ScrollView重寫了父類viewGroup的measureChildWithMargins方法: 測量child的高度,傳遞的是UNSPECIFIED(儘可能大的) 再來看看listview ...
  • 效果圖 背景 在公司做的項目裡面,剛好有需要用到微信聊天界面長按彈框樣式這種UI的。 網上找了一下,沒找到。 Android現成的 "ListPopupWindow" 又不能滿足需求。 因此在非上班時間擼一個出來,供大家使用。 示例代碼 關鍵文件、示例代碼及使用方法等我都放到github上了。 這篇 ...
  • <html></html> <body></body> <h1> this is the first heading </h1>..<h5> this is heading 5</h5> <p> this is a paragraph </p><p> this is another </p> 鏈接< ...
  • 主要問題:1、構造函數和普通函數有區別麽?什麼區別?2、prototype和__proto__有什麼不同?3、instanceof的作用機制,為什麼有限制?4、ES6的相關方法,Class繼承原理? ...
  • a.random:hover{ color:#64FFDA; font-size:120%; } //選擇的是class="random"的<a>標簽。 a#search:active{ font-size:80%; } //選擇的是id="search"的<a>標簽。 ...
  • 本文實例講述了jQuery中animate()方法用法。分享給大家供大家參考。具體分析如下: 此方法用於創建自定義動畫,並且能夠規定動畫執行時長、擦除效果。動畫完成後還可以地觸發一個回調函數。 animate()方法的使用: 方式一: 以“屬性名/值”對象的方式定義動畫終止樣式屬性。例如: 代碼如下 ...
  • 概念:Bootstrap將會根據你的屏幕的大小來調整HTML元素的大小 —— 強調 響應式設計的概念。 通過響應式設計,你無需再為你的網站設計一個手機版的。它在任何尺寸的屏幕上看起來都會不錯。 Bootstrap自帶了一些預定義的按鈕顏色。淺藍色 btn-info 被用在那些用戶可能會採取的操作上 ...
  • 1、父標簽 position屬性為relative; 2、問題標簽無position屬性(不包括static); 3、問題標簽含有浮動(float)屬性。 4、問題標簽的祖先標簽的z-index值比較小 如果這樣的話 position只還剩下absolute跟fixed了喔 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...