2016-08-16 10 views
-1

Ich habe einen kleinen JavaScript-Code, in dem ich versuche setTimeout zu verwenden, entweder auf eine externe Eingabe warten (über responseReceived Variable) ODER warten auf eine maximale Schwelle Zeit und dann kündige.Funktion aufgerufen in SetTimeout wird nicht aufgerufen

Hier ist der Code:

var MAX_WAIT_THRESHOLD = 5000; 
var keepWaiting = true; 
var waitInterval = 500; 
var totalTimeWaited = 0; 

alert("Alert1"); 

while(keepWaiting == true) { 
    setTimeout(function() { 
    totalTimeWaited = totalTimeWaited + waitInterval; 
    alert("Alert2"); 
    if(responseReceived == true || totalTimeWaited >= MAX_WAIT_THRESHOLD) { 
     keepWaiting = false; 
    } 
    }, waitInterval); 
} 

Das Problem aus irgendeinem Grund ist setTimeout(..) eigentlich nie ruft die anonyme Funktion darin erstellt. Ich habe dies überprüft, indem ich Haltepunkte in das JavaScript-Ausführungssteuerelement von Google gesetzt habe, und die Ausführung stoppt an keinem Haltepunkt innerhalb der anonymen Funktion. Die Ausführung von JavaScript wechselt zwischen der while .. Zeile und der setTimout(..) Zeile. responseReceived wird an anderer Stelle im Code festgelegt. Eine andere Möglichkeit, dies zu sagen, ist, dass die erste Warnung (Alert1) anzeigt, die zweite jedoch nie (Alert2).

Was mache ich falsch?

EDIT:

Ich ging durch die ‚Duplikat‘ Frage berichtet, aber ich sehe nicht, wie das zu meiner Frage relevant ist. Meine Frage bezieht sich nicht auf die while Schleife. Es geht vielmehr darum, warum die interne anonyme Funktion nicht aufgerufen wird.

+2

Mögliches Duplikat von [Javascript - warte bis flag = true] (http://stackoverflow.com/questions/22125865/jascript-wait-until-flag-true) –

+0

Ich bin nicht sicher, wie diese Frage verbunden ist die ich frage. Ich weiß, dass JavaScript single-threaded ist. Das Problem ist nicht mit der 'while' Schleife. Das Problem ist, dass die interne anonyme Funktion aus irgendeinem Grund nicht aufgerufen wird. – Ahmad

+2

Das liegt daran, dass die "while" -Schleife niemals endet, sodass der Timer nie eine Chance bekommt (single threaded). –

Antwort

1

Ihr Code hat meine Browser-Registerkarte gelöscht. : D

Warum verwenden Sie nicht einfach setInterval und entfernen Sie die while Schleife?

var MAX_WAIT_THRESHOLD = 5000; 
var waitInterval = 500; 
var totalTimeWaited = 0; 
var waiting = true; 

alert("Alert1"); 

var interval = setInterval(function() { 
    totalTimeWaited += waitInterval; 
    alert("Alert2"); 
    if (responseReceived || totalTimeWaited >= MAX_WAIT_THRESHOLD) { 
    // stop waiting 
    clearInterval(interval); 
    waiting = false; 
    alert("Done"); 
    } 
}, waitInterval); 
0

Dieses Problem wird mit den javascript concurrency model verwendet.

Soweit ich weiß, können alle Ihre setTimeout-Callbacks nur ausgeführt werden, nachdem die while-Schleife beendet wurde, da diese while-Schleife eine Nachricht ist, die die Warteschlange blockiert. Aber in diesem Fall endet es nie. Es gab einen weiteren SO-Thread, der das erklärte, aber ich kann es jetzt nicht finden.

Ich sehe, dass Sie tatsächlich die maximale Zeit der Schleife mit Kontrollvariablen steuern. Da sich dieser Steuercode jedoch innerhalb eines setTimeout-Callbacks befindet, wird er erst in die Warteschlange gestellt, wenn die Schleifen enden. Daher wird das Steuerelement var keepWaiting innerhalb der Schleife niemals auf false gesetzt. Sollten Sie diesen Steuercode außerhalb der setTimeout Funktion übernehmen, wäre es nicht den Browser brechen und an einem gewissen Punkt wird die ‚alert 2‘ Nachricht -mehrere mal zeigen, in fakten:

var MAX_WAIT_THRESHOLD = 5000; 
var keepWaiting = true; 
var waitInterval = 500; 
var totalTimeWaited = 0; 
var responseReceived = false; 

console.log("Alert1"); 

while(keepWaiting == true) { 
setTimeout(function() { 

console.log("Alert2"); 

}, waitInterval); 

    totalTimeWaited = totalTimeWaited + waitInterval; 
    if(responseReceived == true || totalTimeWaited >= MAX_WAIT_THRESHOLD) { 
    keepWaiting = false; 
    } 
} 

jedoch alle Rückrufe werden Feuer am Ende aus den zuvor aufgedeckten Gründen.

Wenn Sie eine ewige Schleife von setTimeouts wollen, verwenden Sie Rekursion statt Iteration.

Verwandte Themen