亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

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

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

javascript基礎修煉(5)—Event Loop(Node.js)

發布時間:2020-08-22 22:52:08 來源:網絡 閱讀:645 作者:大史不說話 欄目:開發技術

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

javascript基礎修煉(5)—Event Loop(Node.js)

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

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

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的原理

javascript基礎修煉(5)—Event Loop(Node.js)

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

【極力推薦文章】

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)

題目分析:

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

javascript基礎修煉(5)—Event Loop(Node.js)

將代碼塊放入事件循環:

javascript基礎修煉(5)—Event Loop(Node.js)

分析:

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

接下來看一下當執行至Fn2時發生的事情:
javascript基礎修煉(5)—Event Loop(Node.js)

分析:

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

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

javascript基礎修煉(5)—Event Loop(Node.js)

分析:

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/刷新率)就可以了。

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

向AI問一下細節

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

AI

进贤县| 延寿县| 玛纳斯县| 淳化县| 广水市| 五寨县| 甘谷县| 曲靖市| 菏泽市| 和静县| 安阳市| 舞钢市| 从江县| 东平县| 杂多县| 万安县| 井研县| 巫山县| 辉南县| 宣汉县| 婺源县| 定南县| 盐亭县| 镇平县| 正镶白旗| 平定县| 宣汉县| 晋宁县| 科尔| 洪江市| 商南县| 罗平县| 环江| 华容县| 库尔勒市| 西盟| 嘉善县| 炉霍县| 榆林市| 贞丰县| 板桥市|