国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

寫一個JavaScript框架:比setTimeout更棒的定時執行

移動開發
這是 JavaScript 框架系列的第二章。在這一章里,我打算講一下在瀏覽器里的異步代碼不同執行方式。你將了解定時器和事件循環之間的不同差異,比如 setTimeout 和 Promises。這個系列是關于一個開源的客戶端框架,叫做 NX。在這個系列里,我主要解釋一下寫該框架不得不克服的主要困難。

[[177395]]

這是 JavaScript 框架系列的第二章。在這一章里,我打算講一下在瀏覽器里的異步代碼不同執行方式。你將了解定時器和事件循環之間的不同差異,比如 setTimeout 和 Promises。

這個系列是關于一個開源的客戶端框架,叫做 NX。在這個系列里,我主要解釋一下寫該框架不得不克服的主要困難。如果你對 NX 感興趣可以參觀我們的 主頁

這個系列包含以下幾個章節:

  1. 項目結構
  2. 定時執行 (當前章節)
  3. 沙箱代碼評估
  4. 數據綁定介紹
  5. 數據綁定與 ES6 代理
  6. 自定義元素
  7. 客戶端路由

異步代碼執行

你可能比較熟悉 Promise、process.nextTick()、setTimeout(),或許還有 requestAnimationFrame() 這些異步執行代碼的方式。它們內部都使用了事件循環,但是它們在精確計時方面有一些不同。

在這一章里,我將解釋它們之間的不同,然后給大家演示怎樣在一個類似 NX 這樣的先進框架里面實現一個定時系統。不用我們重新做一個,我們將使用原生的事件循環來達到我們的目的。

事件循環

事件循環甚至沒有在 ES6 規范里提到。JavaScript 自身只有任務(Job)和任務隊列(job queue)。更加復雜的事件循環是在 NodeJS 和 HTML5 規范里分別定義的,因為這篇是針對前端的,我會在詳細說明后者。

事件循環可以被看做某個條件的循環。它不停的尋找新的任務來運行。這個循環中的一次迭代叫做一個滴答(tick)。在一次滴答期間執行的代碼稱為一次任務(task)。

  1. while (eventLoop.waitForTask()) {   
  2.   eventLoop.processNextTask() 

任務是同步代碼,它可以在循環中調度其它任務。一個簡單的調用新任務的方式是 setTimeout(taskFn)。不管怎樣, 任務可能有很多來源,比如用戶事件、網絡或者 DOM 操作。

 [[177396]]

 

任務隊列

更復雜一些的是,事件循環可以有多個任務隊列。這里有兩個約束條件,相同任務源的事件必須在相同的隊列,以及任務必須按插入的順序進行處理。除此之外,瀏覽器可以做任何它想做的事情。例如,它可以決定接下來處理哪個任務隊列。

  1. while (eventLoop.waitForTask()) {   
  2.   const taskQueue = eventLoop.selectTaskQueue() 
  3.   if (taskQueue.hasNextTask()) { 
  4.     taskQueue.processNextTask() 
  5.   } 

用這個模型,我們不能精確的控制定時。如果用 setTimeout()瀏覽器可能決定先運行完其它幾個隊列才運行我們的隊列。

 

[[177397]]

 

微任務隊列

幸運的是,事件循環還提供了一個叫做微任務(microtask)隊列的單一隊列。當前任務結束的時候,微任務隊列會清空每個滴答里的任務。

  1. while (eventLoop.waitForTask()) {   
  2.   const taskQueue = eventLoop.selectTaskQueue() 
  3.   if (taskQueue.hasNextTask()) { 
  4.     taskQueue.processNextTask() 
  5.   } 
  6.   const microtaskQueue = eventLoop.microTaskQueue 
  7.   while (microtaskQueue.hasNextMicrotask()) { 
  8.     microtaskQueue.processNextMicrotask() 
  9.   } 

最簡單的調用微任務的方法是 Promise.resolve().then(microtaskFn)。微任務按照插入順序進行處理,并且由于僅存在一個微任務隊列,瀏覽器不會把時間弄亂了。

此外,微任務可以調度新的微任務,它將插入到同一個隊列,并在同一個滴答內處理。

 

[[177398]]

 

繪制Rendering

***是繪制Rendering調度,不同于事件處理和分解,繪制并不是在單獨的后臺任務完成的。它是一個可以運行在每個循環滴答結束時的算法。

在這里瀏覽器又有了許多自由:它可能在每個任務以后繪制,但是它也可能在好幾百個任務都執行了以后也不繪制。

幸運的是,我們有 requestAnimationFrame(),它在下一個繪制之前執行傳遞的函數。我們最終的事件模型像這樣:

  1. while (eventLoop.waitForTask()) {   
  2.   const taskQueue = eventLoop.selectTaskQueue() 
  3.   if (taskQueue.hasNextTask()) { 
  4.     taskQueue.processNextTask() 
  5.   } 
  6.   const microtaskQueue = eventLoop.microTaskQueue 
  7.   while (microtaskQueue.hasNextMicrotask()) { 
  8.     microtaskQueue.processNextMicrotask() 
  9.   } 
  10.   if (shouldRender()) { 
  11.     applyScrollResizeAndCSS() 
  12.     runAnimationFrames() 
  13.     render() 
  14.   } 

現在用我們所知道知識來創建定時系統!

利用事件循環

和大多數現代框架一樣,NX 也是基于 DOM 操作和數據綁定的。批量操作和異步執行以取得更好的性能表現。基于以上理由我們用 Promises、 MutationObservers 和 requestAnimationFrame()。

我們所期望的定時器是這樣的:

  1. 代碼來自于開發者
  2. 數據綁定和 DOM 操作由 NX 來執行
  3. 開發者定義事件鉤子
  4. 瀏覽器進行繪制

步驟 1

NX 寄存器對象基于 ES6 代理 以及 DOM 變動基于MutationObserver (變動觀測器)同步運行(下一節詳細介紹)。 它作為一個微任務延遲直到步驟 2 執行以后才做出反應。這個延遲已經在Promise.resolve().then(reaction) 進行了對象轉換,并且它將通過變動觀測器自動運行。

步驟 2

來自開發者的代碼(任務)運行完成。微任務由 NX 開始執行所注冊。 因為它們是微任務,所以按序執行。注意,我們仍然在同一個滴答循環中。

步驟 3

開發者通過 requestAnimationFrame(hook) 通知 NX 運行鉤子。這可能在滴答循環后發生。重要的是,鉤子運行在下一次繪制之前和所有數據操作之后,并且 DOM 和 CSS 改變都已經完成。

步驟 4

瀏覽器繪制下一個視圖。這也有可能發生在滴答循環之后,但是絕對不會發生在一個滴答的步驟 3 之前。

牢記在心里的事情

我們在原生的事件循環之上實現了一個簡單而有效的定時系統。理論上講它運行的很好,但是還是很脆弱,一個輕微的錯誤可能會導致很嚴重的 BUG。

在一個復雜的系統當中,最重要的就是建立一定的規則并在以后保持它們。在 NX 中有以下規則:

  1. 永遠不用 setTimeout(fn, 0) 來進行內部操作
  2. 用相同的方法來注冊微任務
  3. 微任務僅供內部操作
  4. 不要干預開發者鉤子運行時間

規則 1 和 2

數據反射和 DOM 操作將按照操作順序執行。這樣只要不混合就可以很好的延遲它們的執行。混合執行會出現莫名其妙的問題。

setTimeout(fn, 0) 的行為完全不可預測。使用不同的方法注冊微任務也會發生混亂。例如,下面的例子中 microtask2 不會正確地在 microtask1 之前運行。

  1. Promise.resolve().then().then(microtask1)   
  2. Promise.resolve().then(microtask2)  [[177399]]

規則 3 和 4

分離開發者的代碼執行和內部操作的時間窗口是非常重要的。混合這兩種行為會導致不可預測的事情發生,并且它會需要開發者了解框架內部。我想很多前臺開發者已經有過類似經歷。

結論

如果你對 NX 框架感興趣,可以參觀我們的主頁。還可以在 GIT 上找到我們的源代碼。

在下一節我們再見,我們將討論 沙盒化代碼執行!

你也可以給我們留言。

責任編輯:龐桂玉 來源: Linux中國
相關推薦

2012-01-04 13:55:23

Canvas

2020-02-25 20:55:20

JavaScript開發 技巧

2014-02-14 09:37:01

JavascriptDOM

2017-03-06 14:08:38

JavaScript單線程setTimeout

2017-06-08 15:53:38

PythonWeb框架

2022-02-10 07:41:02

JavaScriponce函數

2023-03-01 10:19:23

2021-05-06 10:52:09

Java Spring Bo框架

2021-02-20 09:45:02

RPC框架Java

2013-01-14 09:44:58

JavaScriptJSJS框架

2015-08-24 10:13:48

javascript圖表庫

2015-06-19 11:08:05

JavaScript圖表庫

2015-06-29 11:30:07

JavaScript小烏龜推箱子

2016-12-20 13:55:52

2011-04-25 08:53:47

JavaScript框架

2024-01-15 00:35:23

JavaScript框架HTML

2022-09-01 11:48:45

JavaScript框架

2020-10-16 08:26:07

JavaScript開發技術

2014-08-19 09:39:46

程序員

2015-10-12 16:45:26

NodeWeb應用框架
點贊
收藏

51CTO技術棧公眾號

成人久久一区二区三区| 官网99热精品| www.成人.com| 亚洲精品日韩一| 男女高潮又爽又黄又无遮挡| 美国一区二区三区在线播放| 精品久久精品久久| 91精品国产福利在线观看麻豆| 性色av一区二区咪爱| 日韩欧美另类中文字幕| 中文字幕精品视频| 免费在线中文字幕| 精品日韩99亚洲| 免费av在线网站| 欧美视频一区在线观看| 国产片在线观看| 天天影视网天天综合色在线播放| 国产国产人免费人成免费视频| 中文字幕欧美激情一区| 狠狠热免费视频| 国产精品毛片无遮挡高清| www.com黄色片| 自拍偷拍亚洲激情| av在线dvd| 婷婷久久综合九色综合绿巨人| 中文字幕在线资源| 色综合久久中文字幕综合网| 四虎影视在线播放| 欧美日韩一区二区三区免费看| 成年在线电影| 欧美精品色一区二区三区| 国内精品久久久久久野外| 337p亚洲精品色噜噜狠狠| 日皮视频在线观看| 亚洲欧美日韩精品久久亚洲区| 成人免费视频观看| 欧美激情精品久久久久久| 欧美男同视频网| 国产精品视频久| 狠狠综合久久| 亚洲精品在线观看免费| 国产精品69毛片高清亚洲| 妞干网在线免费视频| 亚洲精品乱码久久久久| se在线电影| 亚洲人成网站999久久久综合| 国产精品久久久久久久久久久久久久久 | 日本大片在线观看| 欧美老女人在线| 欧美日韩精品免费观看视完整| 久久精品国产清自在天天线| 国产精品xxxav免费视频| 91精品在线观| 黑人巨大精品欧美黑白配亚洲| 欧美一级黄色影院| 欧美日韩一区二区在线播放| 麻豆av在线播放| 97国产精品免费视频| 亚洲精品一二三区区别| 日韩video| 一个色综合网站| 牛牛在线精品视频| 97精品一区二区三区| 99亚洲精品| 亚洲精品高清无码视频| 欧美综合亚洲图片综合区| 日韩av免费| 91午夜在线播放| 国产成人精品网址| 青青草在线播放| 日韩亚洲精品视频| 亚洲天堂男人| 亚洲视频在线a| 欧美一级黄色大片| 综合综合综合综合综合网| 一级黄色录像免费看| 午夜久久久影院| 国产精品亚洲成在人线| 国产综合动作在线观看| 毛片在线视频播放| 成人欧美一区二区三区在线播放| 欧洲不卡视频| 国产91成人video| 国产一区二区中文字幕| 中文字幕在线永久在线视频| 日韩中文字幕视频在线| 99热这里只有精品8| 无限国产资源| 久久艳片www.17c.com| 国产精品一卡| 在线观看麻豆视频| 久久久久久com| 福利91精品一区二区三区| 日本中文字幕伦在线观看| 日本高清不卡的在线| 91在线视频免费观看| 成人影音在线| 精品久久一区二区三区蜜桃| 亚洲黄色免费电影| 精品视频在线播放一区二区三区| 午夜一区二区三区| 欧美四级电影网| 午夜影院欧美| siro系绝美精品系列| 欧美激情视频一区| 丰满岳乱妇一区二区三区| 国产一线二线在线观看| 黑人另类av| 午夜精品免费在线| 久草精品在线| 99热在线免费| 久久全国免费视频| 久久精品一区二区三区av| 高清在线一区| 欧美做受777cos| 日韩黄在线观看| 免费在线观看精品| 日本资源在线| 日本午夜精品电影| 欧美一区二区三区视频在线观看| 黄色一区二区三区四区| 久久天堂电影| 成人av影视在线| 欧美性猛交xxxxxx富婆| 欧美精品日本| 91短视频版在线观看www免费| 天天av综合| 欧美 日韩精品| 色老头一区二区三区| 国精产品一区一区三区mba桃花| 亚洲xxxxxx| 国产精品久久久久av福利动漫| 欧美性xxxx在线播放| 国产大片一区| av免费在线一区二区三区| 国产久一道中文一区| 欧美日韩视频在线第一区 | 日韩国产高清在线| 羞羞的网站在线观看| 日本在线一区| 亚洲精品国产精品国自产观看浪潮| 秋霞午夜av一区二区三区| 日韩大片免费观看| 日韩中文字幕三区| 国语自产精品视频在线看一大j8 | 四季av在线一区二区三区| 美女激情网站| 国产日韩精品综合网站| 91精品福利视频| 亚洲综合精品四区| av高清不卡| 国产免费视频传媒| 青青草一区二区| 在线观看91精品国产入口| 国产精品呻吟| 成人在线观看免费视频| 成人www视频网站免费观看| 91精品国产自产在线观看永久| 欧美日韩国产免费一区二区| 国产在线精品不卡| 国产色噜噜噜91在线精品| 日本不卡视频一区二区| 亚洲欧美日韩另类精品一区二区三区| 中文字幕日韩欧美在线| 亚洲乱码国产乱码精品精98午夜| 午夜精品剧场| 色8久久影院午夜场| 国产日本韩国在线播放| 精品国产乱码久久久久久郑州公司 | 国产精品又粗又长| 九九热99久久久国产盗摄| 午夜影院久久久| 免费在线一区观看| 国产精品对白| 蜜桃av在线免费观看| 欧美一级欧美一级| 国产精品视频99| 亚洲国产精品va在线| 最近中文字幕一区二区三区| 亚洲欧美网站| 奇米影视777在线欧美电影观看 | 日韩第一页在线观看| 久久999免费视频| 欧美亚洲一区二区在线| av电影天堂一区二区在线| 99re6这里只有精品| 色偷偷色偷偷色偷偷在线视频| 黄色免费观看网站| 亚洲春色在线| 国产a∨精品一区二区三区不卡| 欧美一区二区三区四区五区| 国产欧美精品区一区二区三区| 亚洲三级影院| 欧美xxxx在线| 免费电影日韩网站| 国产三级在线| 中文字幕高清20页| 日本精品福利视频| 国产精品二区在线| 欧美又大粗又爽又黄大片视频|