2010-08-02 121 views
2

這js將採取一個值,從它減去X的金額,然後數到該值。Javascript循環&setInterval

我試圖通過做一個簡單的while循環來完成這個任務,但我無法完成它的工作。

我想知道是否有人可以評論如何或爲什麼下面的while循環方法不起作用。

這是我能得到它的工作的唯一辦法:

function _initCountUpUsers() 
{ 
    var totalUsers = $('#totalUsers'); 
    var ceiling = parseInt(totalUsers.html()); 
    var floor = ceiling - 10; 

    function updateTotalUsers() 
    { 
     if(floor < ceiling) 
     { 
      totalUsers.html(floor); 
      floor++; 
     } 
    } 

    window.setInterval(updateTotalUsers, 1000, floor); 
} 

非工作時方法:

function _initCountUpUsers() 
{ 
    var totalUsers = $('#totalUsers'); 
    var ceiling = parseInt(totalUsers.html()); 
    var floor = ceiling - 10; 

    function updateTotalUsers() 
    { 
     totalUsers.html(floor); 
     floor++; 
    } 

    while(floor < ceiling) 
    { 
     window.setInterval(updateTotalUsers, 1000, floor);  
    } 

} 
+0

我想探索while(甚至for)循環方法的原因是我認爲這將是更好的做法或更多學術方法的做法。 – doremi 2010-08-02 18:30:48

+0

它會更乾淨,但它不可行。幸運的是,JavaScript非常靈活 - 你可以想出更接近你想要的東西(看我更新的答案)。 – Shog9 2010-08-02 18:39:16

回答

3

我不知道爲什麼你不想堅持你的第一種方法,但是......

while(floor < ceiling) 
{ 
    window.setInterval(updateTotalUsers, 1000, floor);  
} 

這將啓動10個獨立的定時器,每一套火一次第二,每套增加樓層和更新總用戶,他們都沒有終止。如果他們要開火,你會看到每秒增加十點,而在第一個例子中增加一個。然而,他們都不會真的開火,因爲你會永遠循環等待達到天花板

JavaScript是單線程的。事件(包括定時器)在執行腳本時排隊。所以你的while循環將永遠不會終止,因爲更新它的定時器事件將等待啓動,直到它完成執行!

即使不是這樣,你仍然有十個計時器,每個計時器永遠運行。

您的第一個方法正處於正確的軌道上。你只需要停止計時器:

function _initCountUpUsers() 
{ 
    var totalUsers = $('#totalUsers'); 
    var ceiling = parseInt(totalUsers.html()); 
    var floor = ceiling - 10; 

    function updateTotalUsers() 
    { 
     if(floor < ceiling) 
     { 
      totalUsers.html(floor); 
      floor++; 
     } 
 else { window.clearInterval(timerID); // stop firing the timer once per second } 
    } 

    var timerID = window.setInterval(updateTotalUsers, 1000, floor); 
}

如果您正在尋找寫這稍微乾淨/不易出錯的方式,只是自己編寫了一個小幫手程序:

function while_interval(proc, int) 
{ 
    var timerID = setInterval(function() 
    { 
    if (!proc()) clearInterval(timerID); 
    }, int); 
} 

。 ..和調用它像這樣:

while_interval(function() 
{ 
    if (floor < ceiling) 
    { 
    totalUsers.html(floor); 
    floor++; 
    return true; 
    } 
}, 1000); 

這讓你抽象掉的看家代碼一點點,但更重要的是它迫使你自覺返回true只要你希望INT erval-loop繼續執行。

+0

不錯的例程在你的文章底部,我已經複製/粘貼它 - 但有一個錯誤:你說的地方「clearTimer(timerID);」它應該是「clearInterval(timerID);」 – 2014-05-07 16:32:59

+0

謝謝@安迪!多年後,有人終於注意到 - 修好了!不要猶豫,建議編輯,糾正這種微不足道的錯誤,順便說一句。 – Shog9 2014-05-07 17:14:59

-1
function _initCountUpUsers() 
{ 
    var totalUsers = $('#totalUsers'), 
     ceiling = parseInt(totalUsers.html()), 
     floor = cieling - 10, 
     intRef = null; 

    function updateTotalUsers() 
    { 
     if(floor < ceiling) 
     { 
      totalUsers.html(floor); 
      floor++; 
     } 
     else { 
      window.clearInterval(intRef); 
     } 
    } 

    intRef = window.setInterval(updateTotalUsers, 1000); 
} 

function _initCountUpUsers() 
{ 
    var totalUsers = $('#totalUsers'); 
    var ceiling = parseInt(totalUsers.html()); 
    var floor = cieling - 10; 
    var int; 

    function updateTotalUsers() 
    { 
     if(floor < ceiling) 
     { 
      totalUsers.html(floor); 
      floor++; 
      window.setTimeout(updateTotalUsers, 1000); 
     } 
    } 

    window.setTimeout(updateTotalUsers, 1000); 
} 
+0

是的,這是他說的方法工作...如果你要切換到setTimeout,可能需要額外的代碼來調整定時器滯後。 – Shog9 2010-08-02 18:17:58