2016-06-09 9 views
2

ich die entsprechenden Seiten auf w3schools und anderen ähnlichen Fragen hier gelesen habe, kann aber nicht scheinen zu verstehen, was zu folgend bisschen falsch ist:setTimeout() -Methode in einer while-Schleife

var myfunc03 = function (i) { 
    document.getElementById('d01').innerHTML += 100-i+"<br>"; 
}; 

var myFunc01 = function() { 
    i=0; 
    while (i<100) { 
    setTimeout(myfunc03(i), 1000) 
    i++; 
    } 
}; 

wenn

myFunc01(); 

wird ausgeführt, es gibt keine Pause und alle möglichen Werte für i werden sofort aufgelistet. Ist hier ein logischer Fehler?

+0

Das natürlich auch seinen zweiten Fehler hervorhebt - eine modifizierte Variable zugreift ('I') aus einem Verschluss. Wenn das Zeitlimit ausgelöst wird, wird "i" auf den letzten Wert geändert. –

+1

'setTimeout' erwartet eine' Funktion' als ersten Parameter, aber Sie übergeben das * Ergebnis * von 'myfunc03' (was' unterdefiniert' ist, weil Sie es aufrufen) – haim770

Antwort

1

Die while Schleife wartet nicht auf setTimeout(), um abzuschließen. Sie müssen unterschiedliche Zeitverzögerungen festlegen, damit sie jeweils zu unterschiedlichen Zeiten ausgeführt werden, und den Wert i durch Schließen übernehmen. Auch in Ihrem Fall wird die Funktion zunächst ausgeführt und der Rückgabewert wird als Argument in setTimeout() festgelegt. Sie müssen also entweder die Funktion in einer anonymen Funktion aufrufen oder die Funktion direkt setzen.

var myFunc01 = function() { 
 
    var i = 0; 
 
    while (i < 100) { 
 
    (function(i) { 
 
     setTimeout(function() { 
 
     document.getElementById('d01').innerHTML += 100 - i + "<br>"; 
 
     }, 1000 * i) 
 
    })(i++) 
 
    } 
 
}; 
 

 
myFunc01();
<span id="d01"></span>


Obwohl setInterval() hier verwendet werden können,

var myFunc01 = function() { 
 
    var i = 0; 
 
    // store the interval id to clear in future 
 
    var intr = setInterval(function() { 
 
    document.getElementById('d01').innerHTML += 100 - i + "<br>"; 
 
    // clear the interval if `i` reached 100 
 
    if (++i == 100) clearInterval(intr); 
 
    }, 1000) 
 

 
} 
 

 
myFunc01();
<span id="d01"></span>

-2

die während Verfahren läuft schnell und alle Timeout fast nach dem ersten Sekunde ausgeführt wird .. Was können Sie tun, ist

  1. statt, während Anruf $timeout von myfunc03 für Timeout nächsten Wert
  2. in Ihrem während Anrufs mit zunehmenden Sekunden wie i*1000

auch, wie andere darauf hingewiesen, man kann nicht von setTimeout anonymer Funktion verwenden wie die Funktionen mit params nennen wie

... 
while (i<100) { 
    setTimeout(
    function(i){ 
     myfunc03(i); 
    }, i*1000); 
    i++; 
} 
... 

für die

+0

Bitte arbeiten Sie an Ihren Antworten. das ist weder lesbar noch verständlich – mplungjan

+0

@mplungjan yeah my bad! – insanevirus

+0

Sie haben das Schließproblem nicht angesprochen – mplungjan

0
  • Ich glaube, Sie auf der setTimeout ein Semikolon fehlen, und Sie sollten versuchen, die Argumente in der folgenden Art und Weise übergeben:

    setTimeout(myfunc03, 1000*i, i); 
    
+0

Für moderne Browser ist dies die beste Lösung, weil es die Peinlichkeit der Schließungen vermeidet. Der zweite Parameter sollte jedoch '1000 * i' sein; Andernfalls setzen Sie 100 Timeouts gleichzeitig auf 1s. Vergleichen Sie https://jsfiddle.net/ofpp26or/2/ mit https://jsfiddle.net/ofpp26or/ –

+0

Ja, das ist richtig. Ich wollte nur syntaktisch zeigen, da dies js-Fehler verursacht haben könnte. Er könnte Zeitparameter gemäß seinen logischen Anforderungen verwenden. –

0

Ja. Es gibt zwei Probleme im Code:

  1. Die setTimeout Funktion eine Funktion als erstes Argument akzeptieren, aber in Ihrem Code, myfunc03(i) kehrt nichts
  2. Die while-Schleife treffen Sie nicht benötigt, stattdessen haben Sie rekursive Funktion verwenden. Da die zweite Funktion aufgerufen werden soll, nachdem das erste Timeout ausgelöst wurde.

Beispielcode:

var myfunc03 = function (i) { 
 
    setTimeout(function() { 
 
    document.getElementById('d01').innerHTML += 100-i+"<br>"; 
 
    if (i < 100) { 
 
     i++; 
 
     myfunc03(i); 
 
    } 
 
    }, 1000); 
 
}; 
 

 
var myFunc01 = function() { 
 
    myfunc03(0); 
 
}; 
 

 
myFunc01();
<div id="d01"></div>

0

können Sie tun es einfacher ohne eine Schleife zu verwenden. Der Struktur mit setTimeout() in diesem Fall:

var i = 0; 
function f1() { ... }; 
function f() { 
    f1(); 
    i += 1; 
    setTimeout(function() { 
     if(i < 100) { 
      f(); 
     } 
    }, 1000); 
} 
f(); 

JSFiddle