Warum funktioniert dieser setTimeout-basierte Code in Firefox nicht mit einer kleinen Zeitüberschreitung (funktioniert in Internet Explorer / Chrome)?

Ich habe den folgenden Code, der den Unterschied beim Aufrufen einer Funktion mit langer Laufzeit direkt von einem Ereignis-Trigger im Vergleich zur Verwendung demonstriertsetTimeout().

Gewolltes Verhalten:

Wenn die erste Taste gedrückt wird, erscheint sie gedrückt, die Berechnung dauert einige Sekunden. Wenn die Berechnung abgeschlossen ist, wird die Taste erneut gedrückt und die zweite Spalte wechselt von "noch nicht berechnet" zu "Berechnung abgeschlossen". (Ich werde nicht näher darauf eingehen, warum das passieren soll.es ist in der verknüpften Antwort erklärt.)

Wenn der zweite Knopf gedrückt wird, drückt der Knopf sofort; Die zweite Spalte ändert sich sofort in "Berechnen ...". Wenn die Berechnung einige Sekunden später abgeschlossen ist, wechselt die zweite Spalte von "Berechnen ..." zu "Berechnung abgeschlossen".

Was passiert eigentlich:

Dies funktioniert perfekt in Chrome (beide Tasten verhalten sich wie erwartet)

Das funktioniert perfekt inInternet Explorer 8

Dies funktioniert NICHT in Firefox (v.25), wie es ist. Insbesondere verhält sich die zweite Schaltfläche zu 100% wie die erste.

Ändern des Timeouts insetTimeout() von0 zu1 hat keine Wirkung

Ändern des Timeouts insetTimeout() von0 zu500 funktioniert

Was mich vor ein großes Rätsel stellt.

Nach dem ganzen Grund, warumsetTimeout() funktioniert, während das Fehlen einer nicht funktioniert, sollte die Verzögerung keinen Einfluss darauf haben, wie die Dinge funktionieren,schon seitsetTimeout()Der Hauptzweck ist es, die Reihenfolge der Warteschlangen hier zu ändern, NICHT um Dinge zu verzögern.

Warum funktioniert es also nicht mit Verzögerung 0 oder 1 in Firefox, sondern wie erwartet mit Verzögerung 500 (und mit jeder Verzögerung in Internet Explorer 8 / Chrome)?

UPDATE: Zusätzlich zum Quellcode unten habe ich auch eineJSFiddle. Aus irgendeinem Grund lehnt es JSFiddle jedoch ab, meinen Internet Explorer 8 überhaupt zu laden. Für dieses Testen ist der folgende Code erforderlich.

UPDATE2: Jemand hat die Möglichkeit eines Problems mit der Konfigurationseinstellung angesprochendom.min_timeout_value in Firefox. Ich habe es von 4 auf 0 geändert, den Browser neu gestartet und nichts wurde behoben. Es schlägt immer noch mit einer Zeitüberschreitung von 0 oder 1 fehl und ist mit 500 erfolgreich.

Hier ist mein Quellcode - ich habe ihn einfach in einer HTML-Datei auf Laufwerk C: gespeichert und in allen drei Browsern geöffnet:

<html><body>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>

<table border=1>
    <tr><td><button id='do'>Do long calc - bad status!</button></td>
        <td><div id='status'>Not Calculating yet.</div></td></tr>
    <tr><td><button id='do_ok'>Do long calc - good status!</button></td>
        <td><div id='status_ok'>Not Calculating yet.</div></td></tr>
</table>

<script>
function long_running(status_div) {
    var result = 0;
    for (var i = 0; i < 1000; i++) {
        for (var j = 0; j < 700; j++) {
            for (var k = 0; k < 200; k++) {
                result = result + i + j + k;
            }
        }
    }
    $(status_div).text('calclation done');
}

// Assign events to buttons
$('#do').on('click', function () {
    $('#status').text('calculating....');
    long_running('#status');
});
$('#do_ok').on('click', function () {
    $('#status_ok').text('calculating....');
    window.setTimeout(function (){ long_running('#status_ok') }, 0);
});
</script>
</body></html>

Zum Testen müssen Sie die Grenzen der verschachtelten Schleife in 300/100/100 für Internet Explorer 8 ändern. oder 1000/1000/500 für Chrome, aufgrund der unterschiedlichen Empfindlichkeit des Fehlers "Dieser JS dauert zu lange" in Verbindung mit der Geschwindigkeit der JavaScript-Engine.

Antworten auf die Frage(3)

Ihre Antwort auf die Frage