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