2016-06-08 165 views
0

對於我的網頁中的一個元素,我希望文本每十秒鐘更改一次,並且要更改該類。文本更改很容易,因爲課程更改,但我遇到了for循環的麻煩,我覺得我錯過了一些東西。For循環迭代一次發生一次而不是延遲

我想讓for loop在數組中選擇一個隨機派系,然後將其應用於元素。對於我的測試,我一直在使用console.log而不是DOM操作。

首先,設置我陣列:

var factions = ["Enforcers", "Reapers", "Ular Boys", "Roaches"]; 

然後,我想是一些在參考隨機選擇該陣列的變量:

var x = factions[Math.floor(Math.random()*factions.length)]; 

從這一點,我想能夠在其他地方運行Math.floorMath.random功能。

function reDefine() { 
    x = factions[Math.floor(Math.random()*factions.length)]; 
    console.log(x); 
} 

最後,我想for loop運行200次(我選擇了200倍,因爲它遠遠超越了時間的用戶將被留在網站上),所以我告訴它數到200( i = 0; i < 200)。之後,我希望每次迭代都要等待10秒,所以我有一個延遲10000(毫秒)的Timeout函數。然後,代碼爲reDefine,然後在測試的情況下,console.log變量的新定義爲x

function reChange() { 
    for (var i = 0; i < 200; i++) { 
     setTimeout(function() { 
      reDefine(); 
      console.log("Chosen faction is now: " + x); 
     }, 10000); 
    } 
} 

相反計數到1(第一次迭代),等待10000,然後重新定義x的,它重新定義x二百次,然後記錄他們。

有沒有什麼我在這裏專門做錯了,也許與Timeout函數?

+0

你的意思是說,你的代碼應該在每個派系之間等待10秒(我的回答),或者你在等待時造成同一派系被記錄200次(Praveen的答案)? – ssube

回答

2

有什麼我特意做錯了在這裏,也許與超時功能?

是的!您正在安排一系列延遲迴調,但實際上並沒有等到完成後才能安排下一個回調。

您可以修復與簡單的東西如:

function reChange(currentIndex) { 
    setTimeout(function() { 
    reDefine(); 
    console.log("Chosen faction is now: " + factions[currentIndex]); 

    // If we haven't gotten to the end of the list, queue up another one 
    var nextIndex = ++currentIndex; 
    if (nextIndex < factions.length) { 
     // Enqueue the next faction 
     reChange(nextIndex); 
    } 
    }, 10000); 
} 

請務必注意,function沒有超時的有closure超過currentIndexreChange每個呼叫的價值。也就是說,由於基元(包括數字)是按值傳遞的,所以在以前的任何超時中,下一個調用都不會取代currentIndexClosure in JS can be a tricky thing.

的核心問題是,你的執行,現在的樣子:

  1. 每個項目
    1. 等待
    2. 日誌

而不是:

  1. 當前項目
    1. 等待
    2. 日誌
    3. 重複

因爲JS是單線程的(對於大多數的意圖和目的),setTimeout增加了一個回調稍後執行。它不會block,直到超時過期,像傳統的sleep會做。

+0

道歉,在您回覆我的評論之前,我看到了您的修改,並在查看問題的答案時將其刪除。繼續;這個更優雅的方法是什麼,並且涉及「睡眠」? – Crowes

+0

我稍微清理了一下這個例子,以便更好地顯示*超時回調後* next *項是如何添加到隊列*的。 JS沒有'sleep',因爲它是單線程的;試圖入睡會阻止任何代碼運行並阻止瀏覽器的UI(如果你運行'for(;;)'循環)。 – ssube