2016-11-04 5 views
0

Ich habe ein Problem mit setInterval & clearInterval.
In meinem Code habe ich mehrere Intervalle festgelegt, und wenn die Anzahl auf 0 reduziert, stoppen Sie die Ausführung.Javascript - clearInterval funktioniert nicht, wenn mehrere setInterval

wie unten:

<!DOCTYPE html> 
<html> 
    <head> 
     <meta name="viewport" content="initial-scale=1.0" charset="utf-8"> 
    </head> 
    <body> 
    <body> 
     <script type="text/javascript"> 
      for (var i=0; i<4; i++){ 
       var count = 100; 

       var IntervalID = window.setInterval((function(){ // closure 
        var timeoutID = IntervalID; // temp 
        var countTemp = count; // temp 
        var id = i; 

        return function(){ 
         countTemp --; 
         console.log(id + " " + countTemp); 

         // do something here 

         if (countTemp == 0){         
          clearInterval(timeoutID); // stop the execution 
          console.log(id + " stop"); 
         } 
        } 
       })(), 20); 
      } 
     </script> 
    </body> 
</html> 

Nach der Konsole erscheinen die Stoppmeldung "x stop", alle Anschlagelement außer dem letzten Element (id: 3), ist es immer noch.

Ich versuche, meinen Code in einer anderen Form zu schreiben:

<!DOCTYPE html> 
<html> 
    <head> 
     <meta name="viewport" content="initial-scale=1.0" charset="utf-8"> 
    </head> 
    <body> 
     <script type="text/javascript"> 
      for (var i=0; i<4; i++){ 
       doSomething(i); 
      } 

      function doSomething(id){ 
       var count = 100; 

       var IntervalID = window.setInterval((function(){ // closure 
        var timeoutID = IntervalID; // temp 
        var countTemp = count; // temp 

        return function(){ 
         countTemp --; 
         console.log(id + " " + countTemp); 

         // do something here 

         if (countTemp == 0){         
          clearInterval(timeoutID); // stop the execution 
          console.log(id + " stop"); 
         } 
        } 
       })(), 20); 
      } 
     </script> 
    </body> 
</html> 

Aber diesmal alle Elemente nicht zu stoppen. Ich habe zwei Fragen:
1. Was ist der Unterschied zwischen diesen beiden Code?
2. Wie funktioniert der Code?

Edit:

clearInterval(timeoutID); // stop the execution 

zu

kann
clearInterval(IntervalID); // stop the execution 

Aber andere Leute Antwort lösen:
Wenn Sie nur den Code Arbeit machen wollen, nur eine Zeile in der zweiten Schnipsel ändern was ich bei diesem Problem verwirre.

+0

Was intervalID-s-Wert bei der ist Mal versuchen Sie es zu benutzen? Console.log das aus, direkt unter dem var timeoutID = IntervalID; – Mati

+3

Im ersten Ausschnitt ist die 'timeoutID' für 'i == 0' undefiniert, da der Aufruf von setInterval noch nicht abgeschlossen ist. Also, fügen Sie 'console.log (i +" - "+ IntervalID);' direkt über 'var timeoutID = IntervalID; // temp' zeigt dir '0 - undefined', dann' 1 - 1', '2 - 2',' 3 - 3' – enhzflep

+0

Oh, ich verstehe einen Teil im ersten Snippet, wenn 'countTemp' reduziert wird 0, 'clearInterval (timeoutID);' stoppt tatsächlich vorheriges (in 'id == 1 'Abschnitt, es stoppt' id == 0' execute; 'id == 2' stop' id == 1'; usw. Aber keine einzige Haltestelle "ID == 3", so dass es immer noch geht). – CryMasK

Antwort

0

Das Problem ist, dass die korrekte IntervalID nicht in Ihrer Schließung erfasst wird, bis zum Zeitpunkt der Schließung, hat window.setInterval die ID nicht zurückgegeben, da der Zuweisungsausdruck noch nicht fertig ist.

Ein einfacher Trick kann mit einem Objekt verwendet werden, da sie

in JavaScript-Funktionen als Referenz übergeben werden habe ich die Schleife modifiziert dieses

zu erreichen
for (var i=0; i < 4; i++){ 

    var count = 100; 

    var args = { id: i, counter: count }; 
    var IntervalID = window.setInterval((function(args){ // closure 

     return function(){ 
      args.counter--; 
      console.log(args.id + " " + args.counter) 
      if (args.counter == 0){         
       clearInterval(args.IntervalID); // stop the execution 
       console.log(args.id + " stop"); 
      } 
     }.bind(args); 
    })(args), 20); 

    // by now the correct IntervalID will be captured 
    // as the assignment expression has finished executing 
    args.IntervalID = IntervalID; 
} 
+0

Danke, jetzt verstehe ich klarer. Beantworten Sie meine eigene Frage 1, in der ersten Schnipsel, 'timeoutID' erfassen vorherige' IntervalID', die im Speicher bleiben, so dass nur die letzte nicht aufhören kann. Im zweiten Snippet, rufen Sie eine Funktion und pop von function stack, nachdem es fertig ist, so '' timeoutID' kann keinen Wert erfassen, es ist 'undefined', alle Elemente/intervalIs kann nicht stoppen. – CryMasK

Verwandte Themen