簡體   English   中英

setInterval(javaScript):有沒有已知的錯誤?

[英]setInterval (javaScript): are there known bugs?

100次中99次,這完美地運作:

function a(){
   setInterval("b()",1000); 
   updateText("still working");
}
function b(){
   timer++;
   updateText(timer);
}

偶爾第一個循環等待20秒到2分鍾。 此后它完美運行。 我知道計時器可以在Android手機上暫停(當顯示軟鍵盤時)。 還有其他條件可能延遲setInterval嗎?

首先,強烈建議你提供一個回調( function )作為第一個參數而不是字符串,因為該字符串是在全局范圍內計算的,我們都知道當我們在js中使用eval時會發生不好的事情(相關的eval post: 什么時候JavaScript的eval()不是邪惡的? )。
所以,你的

setInterval("b()", 1000); 

應改寫為:

setInterval(b, 1000); 

要么:

setInterval(function() { b(); }, 1000); 

我還建議您使用setTimeout來模擬setInterval

setInterval函數的主要缺點是它每n毫秒執行一段代碼,而不管前一代碼塊的執行情況如何。
因此,如果由於某種原因, setInterval回調的執行時間比提供的延遲要長,則會導致一些堆棧溢出

我們以下面的代碼為例:

function foo() {
    // this takes about 2 seconds to execute
    // .. code here
}
setInterval(foo, 1000);

這實際上將凍結瀏覽器,因為它將執行foo (幾乎)無限次,但它永遠不會完成它。

在這種情況下的解決方案是使用setTimeout模擬setInterval ,以確保在再次調用之前回調已完成執行:

function foo() {
    // this takes about 2 seconds to execute
    // .. code here
}
function newSetInterval(callback, duration, callbackArguments) {
    callback.apply(this, callbackArguments);
    var args = arguments,
        scope = this;

    setTimeout(function() {
        newSetInterval.apply(scope, args);
    }, duration);
}
newSetInterval(foo, 1000);

現在,只有在前一個實例完成代碼執行后才會再次調用foo

我會對你的代碼應用相同的東西,以便讓瀏覽器決定何時可以執行代碼,而不是強迫它執行代碼塊,因為它在那個時刻是忙碌的:

function a() {
   newSetInterval(b, 1000); 
   updateText("still working");
}
function b() {
   timer++;
   updateText(timer);
}
function newSetInterval(callback, duration, callbackArguments) {
    callback.apply(this, callbackArguments);
    var args = arguments,
        scope=this;

    setTimeout(function() {
        newSetInterval.apply(scope, args);
    }, duration);
}

如果您感興趣,我已經重寫了setIntervalclearInterval函數,以便在任何地方使用它們,而不需要處理堆棧溢出:

function setInterval(f, time) {
    setInterval.ids = setInterval.ids || {};
    setInterval.idCount = setInterval.idCount || 0;
    var that = this,
        id = setInterval.idCount++,
        // to prevent firefox bug that adds an extra element to the arguments
        l = arguments.length - 2;

    (function theFn() {
        // to prevent firefox bug that adds an extra element to the arguments
        var args = [].slice.call(arguments, 0, l);
        f.apply(this, args);
        setInterval.ids[id] = setTimeout.apply(this, [theFn, time].concat(args));
    }).apply(that, [].slice.call(arguments, 2, arguments.length));
    return id;
}


function clearInterval(id) {
    if(!setInterval.ids || !setInterval.ids[id]) {
        return false;
    }
    clearTimeout(setInterval.ids[id]);
    return true;
} 

嘗試這個,

setInterval(b, 1000);

要么

setInterval(function(){
   timer++;
   updateText(timer);
}, 1000);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM