1. 程式人生 > >javascript專精--定時器與計時器

javascript專精--定時器與計時器

1、JavaScript的內在執行邏輯
學習JavaScript中,會出現一些我們難以理解的程式碼。之所以很難理解,我覺得很大程度上,我們對JavaScript的執行環境以及內在機制不夠了解造成的。
var i = 5;
setTimeout(function () {
    i++;
    console.log(i);
},0);
console.log(i);

//執行結果是5,6!!


這段程式碼的執行結果是:5、6。

我想問:為什麼不是6、5?這是為什麼?
其實,這是和JavaScript的內在作用機制有關。一段程式碼的執行,它是有順序的,這個順序是一種優先排列的順序。先把同步的程式碼排列到執行緒上,然後在這個執行緒上執行程式碼。再把其他的非同步程式碼根據一定的規則排布的過程。其實就是JavaScript的執行過程。

特別注意:setTimout(fun,0);並不是0ms之後就會執行,而是0ms之後把程式碼排列到JavaScript程式碼的執行執行緒上。這個執行執行緒只保證儘快執行,不保證立即執行!

所以,示例中的程式碼,它的排布順序就是:
(1)、i = 5;
(2)、console.log(i);
(3)、setTimeout
最終的結果就是,5和6。
2、實際開發中的延時器setTimeout
大多數有經驗的人一般會使用setTimeout作為延時器,而不用setInterval,原因顯而易見--------如果在setInterval的時間間隔內,JavaScript程式碼沒有執行完畢,那樣會出現問題的!(至於什麼問題,後面討論)

一般我們這樣使用一個延時器。
    var i = 0;
    function fun(){
        i++;
        console.log(i);
        setTimeout(function () {
            fun();
        },1000)

    }
    fun();


 這樣的一個好處就是,我等fun中的程式碼執行完畢,我再向後推遲1s執行函式。如果函式fun中進行了大量的dom操作,可能會耗費1s甚至更多的時間執行同步程式碼,setTimeout能夠保證繼續向後延期1s重新開始執行函式。(這樣就不會引起setInterval的處理大量操作而影響排布的問題)

注意:setTimeout 的合理使用,會對瀏覽器效能有很大的提升。
一個經典的示例是onresize事件中操作dom。
window.onresize事件是在視窗變化中不斷觸發的過程,如果在這個過程中,大量的進行dom操作,是非常耗費瀏覽器的效能的,如果這個時候,加一個setTimeout可能效果會好很多。
window.onresize = function(){
    setTimeout(function(){
        //dom操作程式碼
    },200)
}

3、setInterval的適用場景
setInterval有很多的缺點,對於瀏覽器來說,維護setInterval的代價要遠遠高於setTimeout。而且在很多情況下,適用setInterval顯得很雞肋。比如短時間內進行dom操作(這個時間一般在1000ms以內)、大量的資料讀取等等。而且多個setInterval的使用,很可能會引起資源競爭,這對瀏覽器的負荷其實是很不友好的。

但是,setInterval其實還是有好處的!比如它很準時的特性!相對於setTimeout,setInterval是一種固定排列的方式執行程式碼,而setTimeout是一種延期的方式執行程式碼!!
同樣的程式碼,如果setTimeout的邏輯總是把其他的程式碼執行完畢,然後在這之後把自己的程式碼塊排布到執行緒上,而setInterval的邏輯是,只要當前時間自己的程式碼執行完,那麼一定會在週期時間內把自己的程式碼排布到執行緒上。

所以,在精準和實時上,setInterval可能會滿足你的需求。而且週期時間跨度大的情況下,可能setInterval也很不錯。
原文:https://blog.csdn.net/mapbar_front/article/details/78627996