亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

JavaScript定時器實現的原理分析

2019-11-19 18:39:37
字體:
來源:轉載
供稿:網友

JavaScript中的定時器大家基本在平時的開發中都遇見過吧,但是又有多少人去深入的理解其中的原理呢?下面我們就來分析一下定時器的實現原理。

一、儲備知識

在我們在項目中一般會遇見過這樣的兩種定時器,第一種是setTimeOut,第二種是setInterval,這兩種定時器有如下的區別:

1、setTimeout允許設置一個超時對象,超時后執行這個對象,但是只執行一次,無周期

2、setInternval允許設置一個超時對象,超時后執行這個對象,周期等于超時對象指定的時間,周期為無限循環

舉一個簡單的例子來說明一下:

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>blog案例</title></head><body> <script type="text/javascript">  setTimeout("alert('this is test')",2000);  setInterval("console.log('demo');",1000); </script></body></html>

這個運行后的結果是彈出了一次對話框,然后在控制臺可以看到每1秒鐘會向其中輸出demo字樣

二、定時器原理初識

那么問題來了,如下的代碼運行的時候會出現什么情況呢?

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>blog案例</title></head><body> <script type="text/javascript">  setTimeout("alert('定時器!')",0);  alert("測試") </script></body></html>

是先執行alert("測試"),還是先執行alert("定時器")呢,那么我們就來運行一下吧!

運行后的結果是先彈出測試字樣的彈出框,然后才彈出定時器字樣的彈出框,為什么會這樣呢?不是定時器的時間為0就即可執行嗎?

答案不是這樣的,因為JS眾所周知是單線程的,所以很多人會認為在上面的例子中會先阻塞等待定時器執行完成后再執行下面的語句,但是這個也就是單線程的一個缺陷之一吧,為了解決這個問題,引入了異步機制。異步機制主要是利用一個我們平時很少去關注的一個知識點――瀏覽器的多線程。究竟什么是瀏覽器的多線程呢?

三、瀏覽器的多線程

 這里我們就來講解一下,眾所周知,JS是單線程的,但是對于瀏覽器來說JS的執行只不過是在瀏覽器眾多現成中的一條,我們稱之為JS引擎線程。而瀏覽器的其他線程則是通過JS引擎線程在執行到某個特定的功能之后指定給瀏覽器的對應線程。具體的原理詳見圖示:

 從這張圖我們可以知道JS引擎線程首先執行回調函數塊,然后是執行點擊事件回調,接著是執行定時器的線程,最后在執行其他的線程。

以下面的代碼我們來分析一下:

setTimeout("alert('定時器!')",0);alert("測試")

首先JS線程讀取到setTimeout定時器,這個時候就會執行瀏覽器的線程,然后跳過定時器繼續執行,這個時候你就看到了彈出框的內容為測試,然后因為定時器的時間為0,所以一執行定時器線程就會即可將彈出框為定時器字樣的任務添加到主線程(JS引擎線程)的隊列之后,等待JS引擎的調用,這個時候我們看到的結果是先彈出測試,然后再彈出定時器

另外我們要注意在HTML5規范中規定定時器的定時時間不能小于4ms,如果是小于4ms,則默認為4ms,所以在這個例子中的0,默認的是4ms,但是這個在不通過的瀏覽器中的表現是不同的,但是這個一般在項目中是沒有什么印象的,這個只是僅做了解即可。

 好的我們將上面的代碼改寫成這樣,然后我們再來看看效果:

 <script type="text/javascript">  console.time("test");  setTimeout("for(var i=0;i<1000;i++)console.log('定時器!');",1000);  console.log("測試");  console.timeEnd("test"); </script>

    運行后的結果如下:

    這里有幾個知識點:

1、console.time和console.timeEnd這兩個方法是可以獲取在其中間執行的語句所用的時間,從圖中我們可以知道test執行的時間在1ms左右,然而定時器的定時時間是在1000ms左右所以這兩個語句只能計算當前引擎的執行時間,換句話說就是在瀏覽器中的定時器模塊的運行時間是這樣是沒法計算的

2、另外我們可以看到一個現象就是定時器在執行的時候不是一千個定時器的字樣全都一次性的打印出來,而是幾百幾百的增加,這個是為什么呢?這里就涉及到了另外的一個問題,如果是定時器的時間到了,但是定時器中的任務沒有執行完成這個時候會怎樣?

我們上面說過就是定時器的時間到了的情況下,就會向JS引擎線程添加任務,不論任務里面的語句是否執行完成,都會像JS引擎線程隊列中添加,但是剩下的未執行完成的語句怎么辦呢?

程序執行到了定時器任務的時候,就會先把已經在定時器模塊執行過的語句加載一次,然后是繼續執行定時器模塊的剩余語句。(定時器模塊向JS引擎中添加的任務相當于就是C語言中的一個指針,指向的是定時器模塊)

所以,setTimeout我們可以定義為:

在指定時間內, 將任務放入事件隊列,等待js引擎空閑后被執行.

四、setInterval的使用

setInterval最基礎的使用方法是直接當一個循環定時器使用,這里就不舉例說明

對于setInterval(fn, 100)容易產生一個誤區:并不是上一次fn執行完了之后再過100ms才開始執行下一次fn。 事實上,setInterval并不管上一次fn的執行結果,而是每隔100ms就將fn放入主線程隊列,而兩次fn之間具體間隔多久就不一定了,跟setTimeout實際延遲時間類似,和JS執行情況有關。具體的延遲效果與內存等因素有關。

五、定時器的可靠性

雖說定時器在大部分的情況下都是趨于穩定的,但是定時器在使用的時候也存在著一些誤差

如下所示:

<script type="text/javascript">  var time1 = new Date().getTime();  setInterval(function(){   var time2 = new Date().getTime();   console.log("setInterval執行的差值時間:"+(time2-time1));  },1000); </script>

運行的結果如下:

從圖中我們基本可以看出定時器存在著一些小小的誤差就比如第一次的運行時間為1001ms比我們設定的時間多出了1ms,所以得出結論:定時器不是完全的可靠的,存在極小的誤差。這個還是在chrome瀏覽器上面測試的結果,換是在IE瀏覽器測試那又如何呢?

結果顯示,在IE瀏覽器下面的誤差更大

六、定時器的妙用

 定時器在項目中除了可以作為定時的作用外還可以用來做耗時代碼的優化:

 我們假設有這樣的一個場景,就是在某個頁面中要渲染50萬個節點,這個時候對于一般的項目中,直接渲染是不可取的,因為這個時候會占用過多的內存,導致瀏覽器出現了卡死的狀態,用戶誤以為是頁面卡死而  直接關閉瀏覽器或者殺死進程,即使是用戶不關閉頁面這樣給用戶的體驗也是不好的,這個時候我們要怎樣來解決這個問題呢,我們可以利用定時器來優化這個問題首先我們可以把50萬個節點分成多組,每組渲染  的節點數不要過多,然后通過setInterval來進行循環這個既不阻塞JS引擎線程的運行,又不可以提高渲染的消耗時間。從而達到最終的優化渲染。

七、定時器使用注意事項

 如果是項目中有對個定時器的參與那么記得在一個定時器執行結束的時候記得要調用clearInterval或clearTimeout這兩個方法來清除定時器,以免定時器之間互相干擾出現一些抓摸不定的現象

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,同時也希望多多支持武林網!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
www.久久草.com| 国产精品久久国产精品99gif| 国产精品高清在线观看| 91av视频导航| 91精品久久久久久久久中文字幕| 亚洲国产精品va在看黑人| 欧美猛少妇色xxxxx| 欧美日韩免费看| 一区二区欧美日韩视频| 亚洲精品久久久久久下一站| 成人妇女淫片aaaa视频| 日本精品免费一区二区三区| 欧美激情伊人电影| 九九精品在线播放| 日韩在线观看网址| 国产精品一区二区久久精品| 欧美在线激情网| www.日韩视频| 欧美重口另类videos人妖| 亚洲欧洲在线视频| 欧美成年人视频网站| 日韩在线视频观看正片免费网站| 亚洲国产精品一区二区久| 成人性生交xxxxx网站| 国产中文字幕91| 亚洲国产美女久久久久| 亚洲精品大尺度| 黑人巨大精品欧美一区免费视频| 日韩精品在线第一页| 欧美午夜www高清视频| 国产精品美女午夜av| 中文字幕av一区二区三区谷原希美| 91人成网站www| 国产日韩精品一区二区| 中文字幕日本欧美| 亚洲一区二区三区视频| 精品欧美aⅴ在线网站| 国产精品一区久久久| 欧美日韩亚洲一区二区三区| 亚洲国产美女精品久久久久∴| 亚洲第一区第一页| 精品视频一区在线视频| 中文字幕日韩在线视频| 国产精品日日摸夜夜添夜夜av| 亚洲欧美变态国产另类| 2025国产精品视频| 欧美性猛交xxxx黑人| 岛国av在线不卡| 爽爽爽爽爽爽爽成人免费观看| 97人洗澡人人免费公开视频碰碰碰| 欧美激情精品久久久久久蜜臀| 久久天天躁狠狠躁夜夜av| 国产成人精品综合久久久| 欧美激情综合色综合啪啪五月| 欧美尤物巨大精品爽| 97香蕉超级碰碰久久免费的优势| 亚洲片在线观看| 日韩在线精品一区| 久久久久中文字幕2018| 国产热re99久久6国产精品| 久久久久久久久中文字幕| 欧美中文字幕视频在线观看| 亚洲综合精品一区二区| 国产精品女主播| 91免费在线视频| 一色桃子一区二区| 国产精品日韩欧美大师| 国产精品久久久久不卡| 中文字幕日韩在线观看| 精品久久久精品| 亚洲精品成a人在线观看| 91亚洲精品久久久久久久久久久久| 日韩av不卡在线| 久久精品91久久久久久再现| 国产精品日日做人人爱| 欧美一级大片视频| 亚洲国产欧美在线成人app| 欧美日韩国产91| 国产亚洲欧洲黄色| 亚洲视频视频在线| 久久综合伊人77777| 国产在线久久久| 国产精品久久久久久久久久ktv| 在线精品播放av| 日韩精品免费综合视频在线播放| 国产mv免费观看入口亚洲| 国产精品亚洲第一区| 亚洲一区二区三区成人在线视频精品| 欧美亚州一区二区三区| 91av视频在线免费观看| 欧美伊久线香蕉线新在线| 亚洲精品美女在线| 国产成人福利网站| 国产日韩欧美影视| 北条麻妃在线一区二区| 亚洲国产高潮在线观看| 日韩av在线免播放器| 中文字幕日韩欧美精品在线观看| 中文字幕视频一区二区在线有码| 欧美俄罗斯性视频| 亚洲一级片在线看| 色婷婷成人综合| 国产成人精品一区二区| 成人欧美一区二区三区在线湿哒哒| 午夜精品久久久久久久99热| 国产精品美女www爽爽爽视频| 欧美性色xo影院| 国产女同一区二区| 久久国产精品久久久| 欧美放荡办公室videos4k| 精品人伦一区二区三区蜜桃网站| www.久久草.com| 91精品久久久久久久久久另类| 日韩专区在线播放| 日韩一区二区精品视频| 在线亚洲午夜片av大片| 91久久嫩草影院一区二区| 蜜月aⅴ免费一区二区三区| 欧美日韩日本国产| 亚洲图中文字幕| 91精品国产电影| 国产精品久久久av| 福利视频第一区| 国产精品久久久久久久午夜| 欧美日韩高清在线观看| 欧美在线www| 精品国内亚洲在观看18黄| 欧美精品videofree1080p| 超碰精品一区二区三区乱码| 亚洲大尺度美女在线| 欧美诱惑福利视频| 日韩免费观看av| 色先锋资源久久综合5566| 精品国产区一区二区三区在线观看| 欧美性生交xxxxxdddd| 欧美国产日产韩国视频| 亚洲欧美色婷婷| 毛片精品免费在线观看| 日韩成人在线播放| 成人网欧美在线视频| 国产精品老牛影院在线观看| 国产精品专区h在线观看| 中文字幕av一区二区| 精品国产视频在线| 精品无码久久久久久国产| 国产精品网红福利| 亚洲a在线观看| 亚洲欧洲日产国码av系列天堂| 亚洲一区二区久久久久久| 日韩精品久久久久久福利| 国产一区二区三区在线免费观看| 日韩电影免费在线观看中文字幕| 清纯唯美亚洲综合| 亚洲xxx视频| 欧美激情精品久久久| 色青青草原桃花久久综合| 精品久久久久久亚洲国产300| 欧美日韩中国免费专区在线看| 国产欧美精品久久久| 这里只有精品在线观看| 日韩中文字幕网址| 久久成人综合视频| 亚洲国产成人精品久久久国产成人一区| 亚洲视频欧美视频|