javascript基礎修煉(5)—Event Loop

来源:https://www.cnblogs.com/dashnowords/archive/2018/09/16/9649829.html
-Advertisement-
Play Games

開發者的javascript造詣取決於對【動態】和【非同步】這兩個詞的理解水平。 一. 一道考察非同步知識的面試題 題目是這樣的,要求寫出下麵代碼的輸出: 如果沒有詳細鑽研過非同步隊列,答對的可能性很低。題目的考察點很明確,就是 中最核心的特點之一的【非同步】,瞭解了原理以後,你就會明白 中聲稱的“無阻塞” ...


開發者的javascript造詣取決於對【動態】和【非同步】這兩個詞的理解水平。

一. 一道考察非同步知識的面試題

題目是這樣的,要求寫出下麵代碼的輸出:

setTimeout(() => {
  console.log(1)
}, 0)
new Promise((resolve, reject) => {
  console.log(2)
  for (let i = 0; i < 10000; i++) {
    i === 9999 && resolve()
  }
  console.log(3)
}).then(() => {
  console.log(4)
})
console.log(5)

如果沒有詳細鑽研過非同步隊列,答對的可能性很低。題目的考察點很明確,就是javascript中最核心的特點之一的【非同步】,瞭解了原理以後,你就會明白javascript中聲稱的“無阻塞”並不是完全成立的,通過一些小辦法就可以讓setTimeout( )的回調永遠都無法被執行,儘管這看起來除了滿足整蠱需求以外並沒有什麼明顯的實用價值。

對Event Loop的理解,帶給開發者的是對代碼整個生命周期更精細的控制能力,儘管在依賴於SPA框架的開發中你幾乎不會用到它們。

二. Event Loop的原理

(上圖來自下麵推薦的這篇博文)

【極力推薦文章】

https://github.com/nswbmw/node-in-debugging/blob/master/3.6%20Event%20Loop.md

並不是筆者偷懶不想寫這一節,而是在讀過了這篇教程以後,自認為除非是剖析更底層的libuv的原理,否則僅就理解Event Loop而言,筆者自己認為不會比這篇寫的清晰。

三. 解析最後一題

上文中給出了從簡單到複雜共6道題來供讀者自檢,算是非常貼心了,本文中針對最後一題進行一些講解。你會發現只要理解了Event Loop 的基本原理後,分析這類代碼基本就是一個【完形填空】的過程

題目如下:

setImmediate(() => {
  console.log(1)
  setTimeout(() => {
    console.log(2)
  }, 100)
  setImmediate(() => {
    console.log(3)
  })
  process.nextTick(() => {
    console.log(4)
  })
})
process.nextTick(() => {
  console.log(5)
  setTimeout(() => {
    console.log(6)
  }, 100)
  setImmediate(() => {
    console.log(7)
  })
  process.nextTick(() => {
    console.log(8)
  })
})
console.log(9)

題目分析:

為了方便分析,先做代碼分塊:

將代碼塊放入事件迴圈:

分析:

這裡有必要說明一下Fn2的位置,文中並沒有明確提及同步代碼執行完畢後進入非同步隊列時會先經歷Tick階段,就圖示而言,每一個巨集觀任務階段之間都會檢查Tick隊列(你也可以理解為每次函數的調用棧被清空的時候會檢查一次Tick隊列),那麼Fn2的待執行時序也就很好理解了。為了方便分析,將console.log(n)相關的方法稱為cln

接下來看一下當執行至Fn2時發生的事情:

分析:

Tick隊列中的process.nextTick( )回調會直接加入Tick隊列(此處就可以實現篇頭講到的阻塞事件迴圈)。另外講一下CL6這個回調,它上面綁定了一個100ms的定時器,在後續的TimersIO Polling中都會檢查倒計時是否到期,到了就執行,沒到就等下一次TimersIO Polling階段再檢查。從上例來看,推遲100ms的CL6在沒有其他干擾的情況下幾乎一定會在N個event loop以後才被執行。

同樣的道理來拆分一下Fn1:

分析:

CL6CL2先開始計時,所以倒計時100ms先到,當然這是N個事件迴圈以後的事情了。

所以從上面的時序就可以看到輸出的結果:9 5 8 1 7 4 3 6 2

【思考題】:

外加一個思考題,如果上例中CL6CL2的延遲都是0,結果是怎樣的呢?

四. requestAnimationFrame

requestAnimationFrame()很多時候會被拿來和setTimeout()作對比,這個API是瀏覽器環境下為了實現高性能幀動畫而設計的,它的主要目的是為了讓瀏覽器的重繪能夠配合顯示設備的刷新率而去掉不必要的性能開銷,常見的顯示設備刷新率為60Hz,相當於你每1000/60≈16.7ms只能看屏幕一眼,得到的信息都是依靠這些離散畫面的視覺暫留拼湊起來的,那如果動畫元素在你看屏幕的時間間隔中像素位移過大的話,看起來就會是一卡一卡的,也就是平時常說的“丟幀”,從Event Loop的角度來講的話,將其近似理解為setTimeout(fn, 1000/刷新率)就可以了。

編輯/尋水的魚
本文首發於華為雲社區:原文鏈接


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

-Advertisement-
Play Games
更多相關文章
  • @at-root與&配合使用(找父級) scss.style css.style 應用於@keyframe scss.style css.style @at-root (without: ...)和@at-root (with: ...) 預設@at-root只會跳出選擇器嵌套,而不能跳出@medi ...
  • sass具有運算的特性,可以對數值型的Value(如:數字、顏色、變數等)進行加減乘除四則運算。 請註意運算符前後請留一個空格,不然會出錯。 scss.style css.style ...
  • sass的嵌套包括兩種: 1、選擇器的嵌套。(最常用到) 指的是在一個選擇器中嵌套另一個選擇器來實現繼承,從而增強了sass文件的結構性和可讀性。 在選擇器嵌套中,可以使用&表示父元素選擇器 scss.style css.style 2、屬性嵌套 指的是有些屬性擁有同一個開始單詞,如border-w ...
  • @if判斷 @if可一個條件單獨使用,也可以和@else結合多條件使用 scss.style css.style 三目判斷 語法為:if($condition, $if_true, $if_false) 。 三個參數分別表示:條件,條件為真的值,條件為假的值。 scss.style css.styl ...
  • 一、摘要 小程式中我們會經常使用到this.data與this.setData。其中this.data是用來獲取頁面data對象的,而this.setData是用來更新界面的。那麼他們之間的區別與聯繫你真的搞懂了嗎? 二、正文 this.data可以獲取頁面data對象,但是它返回的對象到底是新的對 ...
  • 工作上使用到element-ui tree 組件,主要功能是要實現節點拖拽和置頂,通過自定義內容方法(render-content)渲染樹代碼如下~ 1 <template> 2 <div class="sortDiv"> 3 <el-tree :data="sortData" draggable ...
  • 你可能不知道的setInterval的坑 之前印象中一直記得setInterval有一些坑,但是一直不是很清楚那些坑是什麼。今天去摸索了下之後,決定來做個記錄以免自己忘記,也希望讓更多人瞭解到這個坑。 坑的地方 1. setInterval會無視代碼的錯誤。就算遇到了錯誤,它還是會一直迴圈下去,不會 ...
  • 第一步先安裝nmp 在node.js的官網下載即可。 第二步 直接安裝剛下載好的node.js即可,(這裡建議不要修改node.js的安裝路徑),傻瓜式直接下一步即可 檢測是否安裝成功: 在cmd的控制台直接輸入node -v 如果出現這樣的界面恭喜你node.js安裝成功 (利用 win + r ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...