2017-06-25 7 views
0

Ich möchte alle 5 Sekunden ein Array ("Sites") durchlaufen. Nach 5 ("cycle_timeout") Sekunden möchte ich eine andere Funktion aufrufen, die Werte von 0 bis 120 in 1-Sekunden-Intervallen durchläuft. Wenn die looper-Funktion außerhalb des Zyklus aufgerufen wird, funktioniert es gut, aber ich möchte, dass es innerhalb des Zyklus aufgerufen wird. Wenn dies passiert, wird der Looper "Delay" nicht beibehalten und die Schleife beschleunigt sehr schnell von 0 auf 120. Wie bekomme ich den Looper, um in 1-Sekunden-Intervallen fortzufahren? Danke für Ihre Hilfe.Javascript loops/functions/setTimeout

var i = 0; 
var l = 120; 
looper(); // looper runs correctly when invoked from here. 
function looper() { 
    var Delay = 1; 
    console.log("i is ", i); 
    i = i + 1; 
    if (i == l) { 
     i = 0; 
    } 
    setTimeout(looper, Delay * 1000); 
} 
var sites = ["a", "b"]; 
var lengthsites = sites.length; 
var ii = 0; 
cycle(); 
function cycle() { 
    console.log("ii is ", ii); 
    console.log("site is ", sites[ii]); 
    var cycle_timeout = 5; 
    setTimeout(cycle, cycle_timeout * 1000); 
    //looper(); // looper accelerates when invoked from here. 
    ii = ii + 1; 
    if (ii == lengthsites) { 
     ii = 0; 
    } 
} 
+0

Wenn Sie Code schreiben, der so aussieht, haben Sie immer Probleme - Einrückung macht Dinge einfacher zu lesen (natürlich können Sie ein Genie sein und brauchen nicht richtig formatierten Code, denke ich) –

+0

Ich konnte nicht helfen Beachten Sie jedoch beim Bearbeiten der Formatierung Ihres Codebeispiels, dass viele Semikolons fehlen. Dies kann alle möglichen unerwarteten Ergebnisse haben und sollte zuerst behoben und getestet werden. Wenn das Problem weiterhin besteht, können wir fortfahren. Siehe [diese Frage] (https://stackoverflow.com/questions/444080/do-you-recommend-using-semicolons-after-every-statement-in-javascript) - obwohl jemand meine Bearbeitung einfach übersteuert und sie "repariert" hat Während ich tippte, wissen wir vielleicht nie, ob das ein Problem war. –

+0

oops - Ich habe das fehlende ';' in den formatierten Code eingefügt, weil ich ein Idiot bin: p –

Antwort

0

Er beschleunigt von innen aus diesem Grund:

function looper() { 
    // stuff 
    callLooperIn1Second(); 
} 

function cycle() { 
    // stuff 
    looper(); 
    callCycleIn5Seconds(); 
} 

Looper wird sich jede Sekunde nennen. Cycle ruft alle 5 Sekunden einen Looper an, der sich jede Sekunde selbst aufruft. Also alle 5 Sekunden ruft cycle wieder looper auf, und es fügt zu den Zeiten hinzu, die geplant werden, um zu laufen. Sie addieren sich zu der Zahl, die looper diese Sekunde genannt wird. Wenn Sie zum ersten Mal cycle anrufen, wird looper einmal pro Sekunde ausgeführt.
Nach 5 Sekunden wird es 2x pro Sekunde ausgeführt.
Nach 10 Sekunden wird es 3x pro Sekunde laufen.

cycle // call looper, which schedules every 1s 
looper 
looper 
looper 
looper 
looper 
cycle // call looper, which schedules every 1s 
looper looper 
looper looper 
looper looper 
looper looper 
looper looper 
cycle // call looper, which schedules every 1s 
looper looper looper 
looper looper looper 
looper looper looper 
looper looper looper 
looper looper looper 

diese setInterval verwenden Schalt würde nicht funktionieren, weil dann bist du nur cycle-setInterval auf looper alle 5 Sekunden verursacht, die etwas weniger Code ist das gleiche Problem zu erreichen.

Ich würde empfehlen, Ihren Fluss- und Terminierungscode von dem zu trennen, was Sie eigentlich vorhaben.

let currentSecond = 0; 
const totalSeconds = 120; 

const sites = ["a", "b", "c"]; 
const totalSites = sites.length; 
let siteIndex = 0; 

function looper (i) { 
    currentSecond = (i + 1) % totalSeconds; 
} 
function cycle (i) { 
    const site = sites[i]; 
    siteIndex = (i + 1) % totalSites; 
} 

function triggerLoop() { 
    const loopDelayMS = 1000; 
    looper(currentSecond); 
    setTimeout(triggerLoop, loopDelayMS); 
} 

function triggerCycle() { 
    const cycleDelayMS = 5000; 
    cycle(siteIndex); 
    setTimeout(triggerCycle, cycleDelayMS); 
} 

function run() { 
    triggerLoop(); 
    triggerCycle(); 
} 

Sie könnten natürlich noch viel weiter machen.
Sie könnten diese Dinge in separaten Intervallen ausführen, anstatt auf rekursiven Timeouts. Das wäre schön.

Sie könnten die Prozesse voneinander abhängig machen, und das ist auch in Ordnung ... außer, dass Sie einen viele mehr Timer-Management-Code hinzufügen müßten, um herauszufinden, wie weit looper ist, in sein Zählen, und was das bedeutet für cycle jedes Mal, wenn es gefeuert wird.

Es sieht nicht so aus, als ob diese beiden Zähler auf irgendeine Weise miteinander verbunden sind. Sie möchten, dass jede Sekunde in 2 Minuten gezählt wird, und Sie möchten, dass die andere alle 5 Sekunden zählt, solange sich Elemente in einem Array befinden und Sie beide zurücksetzen und weiterlaufen lassen möchten, wenn sie ihr Limit erreichen . Soweit ich das beurteilen kann, haben die Timer nichts miteinander zu tun. Es ist nur die Tatsache, dass sie in den Code gebunden sind, der sie sich schlecht benimmt.

Verwandte Themen