2016-04-09 1 views
3

Ich vermute, dass dies ein Duplikat wegen der einfachen Natur der Frage sein könnte, aber ich konnte keine Antwort finden.Reset Timeout des gleichen Timers in einer for-Schleife in Javascript

Ich stelle eine Timeout-Funktion in einer Foor-Schleife ein, wenn eine bestimmte Bedingung zutrifft. Da ich das Timeout nicht innerhalb der Schleife deklarieren möchte, habe ich eine setTimeout-Funktion geschrieben, um es außerhalb zu setzen. Ich möchte nur einen Timer verwenden, der zurückgesetzt wird, wenn er bereits läuft, andernfalls sollte der Timer das erste Mal eingestellt werden. Mein Problem ist, dass die Funktion mehrere Timer setzt, obwohl ich eine clearTimeout() verwende.

Mein Code:

var timeout_id; 
    var things = [true, true, false, true, true]; 

    var setTimer = function(timer_id, duration) { 
     console.log("timer_id: ", timer_id); 
     // clear timeout of the given Id 
     clearTimeout(timer_id); 
     timer_id = setTimeout(function() { 
      // reset flag 
      console.log("Timer timed out"); 
     }, duration); 
     console.log("timer_id: ", timer_id); 
    }; 

    for (var i = things.length - 1; i >= 0; i--) { 
     if (things[i]) { 
      setTimer(timeout_id, 900); 
      console.log("Timer set because value of : " + i + " = ", things[i]); 
     } 
    } 

Was ich in der Konsole ist:

timer_id: undefined 
timer_id: 1 
Timer set because value of : 4 = true 
timer_id: undefined 
timer_id: 2 
Timer set because value of : 3 = true 
timer_id: undefined 
timer_id: 3 
Timer set because value of : 1 = true 
timer_id: undefined 
timer_id: 4 
Timer set because value of : 0 = true 
timer timed out 
timer timed out 
timer timed out 
timer timed out 

Ich verstehe nicht, warum meine timer_id jedes Mal erhöht wird.

Ich gebe die ID und setzen Sie den Timer von ihm. Danach setze ich einen Timer auf die gleiche ID, oder? Wird der Verweis auf die Variable var timeout_id nicht angegeben und ändert er sich innerhalb der setTimer-Funktion?

Danke für die Hilfe.

+0

Sie passieren ' timer_id 'zu der Funktion und Sie setzen das auf setTimeout (...) Wollen Sie nicht stattdessen die Variable' timeout_id 'des äußeren Bereichs verwenden? –

+0

Ich wollte das nicht, weil ich die setTimer-Funktion bei verschiedenen Timer-Variablen aufrufen möchte. Aber überprüfe meine Antwort. Ich denke, ich habe dort eine Lösung gefunden. – Merc

Antwort

1

Ihre setTimer Funktion ändern:

var timer_ids = {}; 

var setTimer = function(timer_id, duration) { 
    console.log("timer_id: ", timer_id); 
    // clear timeout of the given Id 
    clearTimeout(timer_ids[timer_id]); 
    timer_ids[timer_id]= setTimeout(function() { 
     // reset flag 
     console.log("Timer timed out"); 
    }, duration); 
    console.log("timer_id: ", timer_id); 
}; 
+1

Nun, das wäre meine erste Annäherung, aber weil ich mindestens zwei Timer haben möchte (die gleichzeitig laufen sollten), möchte ich definitiv die setTimer Funktion zweimal mit verschiedenen Ids aufrufen. Lets sagen, ich habe einen Timer einen Timer nach einem Klick und einen Timer nach einem Hover zurückgesetzt. Ich brauche verschiedene Timer und möchte aufrufen setTimer (first_timer_id); und setTimer (sec_timer_id); Beide in einer for-Schleife, und das ist, warum ich jedes bei Bedarf zurücksetzen möchte ... – Merc

+0

Oh, also könnten Sie die timeout_id in eine hashmap (Json-Objekt) wo der Schlüssel ist Ihre "Timer" ID, und der Wert ist die timeout_id - wie folgt: clearTimeout (timerIds [timerId]); timerIds [timerId] = setTimeout() ..:; wo timerIds ist die Variable außerhalb der SetTimer Funktionsumfang, ich werde meine Antwort aktualisieren. –

+0

Kühl. Das ist schön. Ich hatte auch einige Kontextprobleme, weil meine setTimer-Funktion eine private Funktion einer separaten «Klasse» ist. Also _this_ war nicht das _dies_ ich erwartete und auch einige Probleme verursachen :). Danke trotzdem. Es hat mein Problem gelöst. – Merc

0

Nun, ich fand kurz darauf eine Lösung. Durch die timeout_id Rückkehr und die Funktion auf der timeout_id Variable laufen bekomme ich nur ein Timer läuft:

var timeout_id; 
    var things = [true, true, false, true, true]; 

    var setTimer = function(timer_id, duration) { 
     console.log("timer_id: ", timer_id); 
     // clear timeout of the given Id 
     clearTimeout(timer_id); 
     timer_id = setTimeout(function() { 
      // reset flag 
      console.log("Timer timed out"); 
     }, duration); 
     console.log("timer_id: ", timer_id); 
     return timer_id; 
    }; 

    for (var i = things.length - 1; i >= 0; i--) { 
     if (things[i]) { 
      timeout_id = setTimer(timeout_id, 900); 
      console.log("Timer set because value of : " + i + " = ", things[i]); 
     } 
    } 

Welche abmeldet:

timer_id: undefined 
timer_id: 1 
Timer set because value of : 4 = true 
timer_id: 1 
timer_id: 2 
Timer set because value of : 3 = true 
timer_id: 2 
timer_id: 3 
Timer set because value of : 1 = true 
timer_id: 3 
timer_id: 4 
Timer set because value of : 0 = true 
Timer timed out 

Sie sehen. Nur ein Timer endet nach 900ms.

4

Frage:

Ich verstehe nicht, warum meine timer_id jedes Mal erhöht wird.

Ich gebe die ID und setzen Sie den Timer von ihm. Danach setze ich einen Timer auf die gleiche Id, nicht wahr?

Ist die Referenz auf die Variable timeout_id nicht angegeben und ändert sie innerhalb der setTimer-Funktion?

Antwort:

Der Grund für die zu dem, was passiert ist, dass Sie eine primitive Anzahl Variable vom Typ sind vorbei.

Primitive Variablen werden als Wert und nicht als Referenz übergeben.

Also in dieser Zeile ...jedes Mal übergeben wird (nicht die Bezugnahme auf timeout_id)

und in dieser Linie

setTimer(timeout_id, 900); 

... der Wert undefiniert ist ...

timer_id = setTimeout(function() { 

... timer_id nicht ist einen Verweis auf timeout_id halten, wie Sie wahrscheinlich erwarten.

Also, was in Ihrem setTimer los ist() Funktion:

Die ersten console.log Ausgänge undefined, weil das ist, was als Parameter übergeben wird.

Die zweite console.log gibt jedes Mal eine inkrementierte ID aus, da dies die Funktion setTimeout() ist, die mit jedem Aufruf zurückgegeben wird.

Der Grund, warum setTimeOut() eine inkrementierte eindeutige Ganzzahl-ID zurückgibt, ist, dass Sie diese ID in einer Variablen halten können, so können Sie diese in Zukunft nutzen können, dass Timeout löschen mit clearTimeout(id)

Here is a nice explanation of 'Passing by Value or by Reference'

+0

Danke für das Teilen. Nicht nein, dass dies nicht als Referenz bestanden wurde. Du hörst nie auf zu lernen. Danke – Merc

+0

Sie sind willkommen –

+0

* wusste nicht (konnte meinen Kommentar nicht bearbeiten, um den Tippfehler zu korrigieren ...) – Merc

Verwandte Themen