談談javascript中的定時器


最近寫一些JS動畫,常用到JS中的定時器(setTimeout & set Interval),查找相關資料,有些心得與大家一起分享。

使用setTimeout & set Interval創建的定時器可以實現有趣且有用的功能,初學者可能對Javascript的定時器有誤解,認為它們是線程,其實Javascript是運行於單線程中的,而定時器僅僅是計划在未來的某個時間執行,而具體的執行時間是不能保證的,因為在頁面的生命周期中,不同的時間可能有其它代碼在控制Javascript的里進程。瀏覽器只是負責進行排序,指派某個代碼在某個時間點運行。

下面說下Javascript線程,下圖表示javascript進程時間線。

image

除了javascript執行進程外,還有一個需要在進程下一次空閑時間執行的代碼隊列,隨着頁面在其生命周期內的推移,代碼會按照執行順序添加到對列中,例如:當一個按鈕被按下時,它的事件處理就會添加到隊列中,並在下一個可能的時間內執行。

定時器對隊列的工作方式是,當特定的時間過去后,將代碼插入,注意添加到隊列並不意味着它會馬上執行,而只能說它會盡快執行,設定一個250ms后執行的定時器,不代表250ms后它會馬上執行,它只會表示在150ms后被加入到隊列中,如果這個時間點隊列是空閑的,那么這段代碼就會被執行。

請看以下代碼:

var btn = document.getElementById("mybtn");
    btn.onclick = function () {
        setTimeout(function () {
            document.getElementById("message").nodeName = "mymessage";
            //其它代碼
        }, 250);
    }

對於定時器最要注意的是:指定的時間間隔表示何時將定時器的代碼添加到隊列中,而不是何時執行代碼。關於這個onclick事伯處理的進程時間線請看下圖:

image

setTimeout() :未來的某時執行代碼 ;clearTimeout() :取消setTimeout()。
下面展示一個簡單的計時,並帶有停止功能:
<script type="text/javascript">
    var c = 0
    var t
    function timedCount() {
        document.getElementById('txt').value = c
        c = c + 1
        t = setTimeout("timedCount()", 1000)
    }

    function stopCount() {
        clearTimeout(t)
    }
</script>

<input type="button" value="開始計時!" onClick="timedCount()">
<input type="text" id="txt">
<input type="button" value="停止計時!" onClick="stopCount()">
 

setInterval() 方法可按照指定的周期(以毫秒計)來調用函數或計算表達式。

setInterval() 方法會不停地調用函數,直到 clearInterval() 被調用或窗口被關閉。由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的參數。

關於重復定時器,我們既可以使用setTimeout來重復創建就時器,也可以直接用setInterval,使用setInterval創建的定時器確保了定時器規則地插入隊列中,這個方式問題在於代碼可能在再次添加到隊列之前還沒有完成執行,可能尋到定時器重復運行好幾次,而中間沒有停頓,然而現在的javascript引擎很聰明,能避免這個問題,當使用setInterval時,僅當沒有定時器的任何其它代碼時,才將定時器代碼添加到隊列中,這樣會確保定時器代碼加入到隊列的時間的間隔是為指定的間隔,請注意這只是加入隊列的時間間隔,並不是執行代碼的時間間隔,所以使用setInterval還是會存在兩個問題:(1)某些間隔會被跳過了(2)多個定時器的代碼執行間隔可能會比預期的要小。

為避免這些問題,可以使用如下模式使用鏈式setTimeout調用:

setTimeout(function () {
        //處理中
        setTimeout(arguments.callee, interval);
    }, interval)

在上面的計時DEMO中也是使用此模式來做循環的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM