setTimeout與setInterval(一)

一. setTimeout

1. 定義

window.setTimeout(func,[delay,param1,param2,····]);
window.setTimeout(code,[delay]);

參數說明:
a. 對於第一行代碼:
func指的是延遲後想執行的函數,delay爲延遲秒數,爲毫秒,最大爲32位有符號整數值,超過最大值即2147483647,將致使函數被當即執行。
param是func的參數,可是這種賦予參數的方法在IE9如下(含IE9)不兼容,可使用polyfill或者外層包裹進行兼容性處理,有興趣能夠點擊這裏
b. 對於第二行代碼:
code指的是可執行代碼,例如javascript

setTimeout(alert("HeiHei"),200)

可是這種方法不推薦,相似eval(),能夠包含可執行代碼,含有安全隱患。html

2. 事件添加的說明

定時器對隊列的工做方式:當特定時間過去後將代碼添加到隊列中,但並不意味着會立刻將執行,設定一個200ms後執行的定時器,指的是在200ms後它將被添加到隊列中,是否執行,還得看隊列中是否沒有其餘的東西。看一下例子:html5

var a=document.getElementById("nav");
    a.onclick=function(){
    setTimeout(alertsomething,200);
    //一些其餘的代碼
}
function alertsomething(){
    alert("it is working");
}

假定onclick處理程序須要執行300ms,這時雖然在205ms添加了定時器代碼,可是仍舊須要等待onclick事件完成後纔可以執行。如圖所示,原本在205ms處添加了定時器代碼,可是因爲此時onclick事件還沒結束,故要等到300ms後才執行定時器代碼
javascript 進程時間線java

3. 清除事件

window.clearTimeout(timeoutID);

4. 對於this的影響

setTimeout調用的代碼,運行在與所在函數徹底分離的執行環境上,在非嚴格模式中,this默認指向global或window,嚴格模式中會拋出undefined,經過call的方式目前也沒法改變,官方的示例以下:chrome

myArray = ["zero", "one", "two"];
myArray.myMethod = function (sProperty) {
    alert(arguments.length > 0 ? this[sProperty] : this);
};
setTimeout.call(myArray, myArray.myMethod, 2000); // error: "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object"
setTimeout.call(myArray, myArray.myMethod, 2500, 2); // same error

對此咱們可使用外加一個匿名函數解決。瀏覽器

setTimeout(function(){myArray.myMethod()}, 2000); // prints "zero,one,two" after 2 seconds
setTimeout(function(){myArray.myMethod('1')}, 2500); // prints "one" after 2.5 seconds

其餘解決方案能夠參照一下參考資料。安全

5. 事件延遲時間大於設定值

a.上文圖中所示,隊列中還有事件未執行完成,須要等待
b.chrome和firefox在未激活的標籤中,會減緩setTimeoutsetInterval的執行,具體緣由能夠參考下文的資料
c.因爲瀏覽器精度的緣由,delay的值最終大於等於4。app

下面是w3c中的原文:less

If the currently running task is a task that was created by the setTimeout() method, and timeout is less than 4, then increase timeout to 4.函數

舉個例子:

setTimeout(function() {
            alert(2);
        }, 0);
        alert(1); //先顯示1,接着才顯示2

2、setInterval

1.定義

跟setTimeout相似

window.setInterval(func, delay[,param1, param2, ...]);
window.setInterval(code, delay);

爲了不多個定時器代碼不間斷連續運行好幾回,當使用setInterval(),僅當沒有該定時器的任何其餘代碼實例時,纔將定時器代碼添加到隊列中,通俗點就是等到上個定時器完成,再添加一個。

2.缺點

  1. 某些間隔會被跳過

  2. 多個定時器的代碼執行之間的間隔可能會比預期小。

圖片描述

在5處,建立一個定時器
205處,添加一個定時器,可是onclick代碼沒執行完成,等待
300處,onclick代碼執行完畢,執行第一個定時器
405處,添加第二個定時器,但前一個定時器沒有執行完成,等待
605處,原本是要添加第三個定時器,可是此時發現,隊列中有了一個定時器,被跳過
等到第一個定時器代碼執行完畢,立刻執行第二個定時器,因此間隔會比預期的小。

3.解決方法

鏈式調用,以下圖所示,主要用於重複定時器

setTimeout(function(){
    //處理代碼
    setTimeout(arguments.callee,interval)
},intercal);

遞歸調用本身。

4. 清除事件

window.clearInterval(intervalID)

3、二者之間的區別

setTimeout方法,在一個指定的時間間隔後運行代碼。
setInterval方法, 每隔一個固定的時間間隔後持續運行指定代碼。

4、參考資料

  1. MDN WindowTimers.setTimeout()

  2. W3C Times

  3. Chrome and Firefox throttle setTimeout/setInterval in inactive tabs

  4. 《JavaScript高級程序設計》Nicholas C.Zakas著 李鬆峯 曹力譯

  5. 你真的瞭解setTimeout和setInterval嗎

相關文章
相關標籤/搜索