javascript
javascript计时原理
2019獨角獸企業重金招聘Python工程師標準>>>
在開始之前,先看一段代碼:
setTimeout(function(){
/* Some long block of code… */
setTimeout(arguments.callee, 10);
}, 10);
setInterval(function(){
/* Some long block of code… */
}, 10);
????計時器通過設定一定的時間段(毫秒)來異步的執行一段代碼。因為 Javascript 是一個單線程語言,計時器提供了一種繞過這種語言限制來執行代碼的能力。
今天就簡單的來說下計時器的工作原理。
JavaScript 提供了三個函數來構建和操作計時器
1 var id = setTimeout(fn, delay);
2 var id = setInterval(fn, delay);
3 clearInterval(id); clearTimeout(id);
為了了解計時器的工作原理,有一個概念必須記在心里:時間延遲不能被保證。什么意思,就是說你這樣寫setTimeout(fn, 500)并不代表fn肯定在500毫秒之后馬上就執行,延遲很可能會更長。因為 JavaScript 是單線程語言,所有的異步事件(包括計時器、鼠標事件或者一個 XMLHttpRequest 完成)僅僅當程序執行期間有缺口的時候才會執行,不是你規定了什么時候就什么時候執行,要知道程序員不是萬能的,你寫的東西最終還是要看瀏覽器臉色的。
理解了下面這幅圖,基本上也就理解的javascript計時器的原理:
????程序開始的時候,執行了一段javascript代碼段,在這個代碼段中,調用了一個timer和一個interval,同時還產生了一個click事件。在大約13秒的時候timer請求執行。但是由于瀏覽器當前正在執行代碼段,因此只有排隊。
????大約18毫秒的時候,代碼段執行完畢,這時候等待的有click和timer任務。瀏覽器同學思考了一下,決定讓click事件優先相應,于是,click事件開始執行,而timer繼續排隊。
????20毫秒的時候,interval的第一次請求執行,于是乎,它也進入排隊。
????29毫秒的時候,click事件處理完畢,瀏覽器先給timer開了后門,隊列中只留下了孤獨的interval,關鍵的時刻來了。這時候,interval的第二次請求來了,而該interval的第一次請求都尚未被相應。如果瀏覽器傻乎乎的直接將他排隊,那么再執行完timer以后,將連續執行兩次interval,這顯然與用戶規定的10ms執行間隔不符,于是在隊列中有上一次未執行的interval任務情況下,瀏覽器會kill掉新到來的interval任務。
????這樣一直執行到第一個interval剛響應完畢的時候,這時候interval第三次請求到來,而這時隊列空空如也。于是interval直接執行。雖然兩次interval的執行間隔為0ms,但是瀏覽器也只好如此了。
????
????因此,可以看出interval和timer最大的區別是interval是每隔10ms固定時間提交一下響應請求,而不能保證響應的間隔時間。因為它提交請求和瀏覽器響應是兩碼事。而timer是在其代碼塊執行完畢以后,才提交下一次請求,即timer start。因此:
setTimeout(function(){
/* Some long block of code… */
setTimeout(arguments.callee, 10);
}, 10);
setInterval(function(){
/* Some long block of code… */
}, 10);
這兩個函數看起來效果一樣,其實不然,第一個代碼塊總會延遲10毫秒執行,雖然大多時候是大于10毫秒的。而第二個每到10毫秒就嘗試執行,不管之前的觸發執行了沒有。
轉載于:https://my.oschina.net/u/2248183/blog/479661
總結
以上是生活随笔為你收集整理的javascript计时原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: config中自定义配置
- 下一篇: SEPM嵌入式数据库损坏的一种修复方法及