Können wir einen requestAnimFrame als 'Ertrag' in der Anwendungsschleife betrachten, damit die Ereignisschleife verarbeitet werden kann?

StackOverflow https://stackoverflow.com//questions/21010396

Frage

Ich benutze das requestAnimFrame Methode in JavaScript, um meine Leinwand in der Hauptschleife meines Programms zu aktualisieren:

window.requestAnimFrame = (function(callback) {
  return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
    function(callback) {
      window.setTimeout(callback, 1000 / 60);
    };
})();


function animate() {
    requestAnimationFrame( animate );
//var runcount = 100;
//for (var i=0;i<=100;i++) {
    draw();
//    if (runcount === i)
//        alert("Completed program loop");
//    }
}

Was geschah, war das mein Programm, das die Zeichenfläche erst aktualisiert hat, nachdem meine Hauptschleife 100 ausgeführt wurde iterationen und dann gestoppt.Nachdem ich das hinzugefügt habe methode oben in meine Hauptschleife, plötzlich bekomme ich Canvas-Updates in jeder Schleife meines Programms.

Die Tatsache, dass der Canvas erst aktualisiert wurde, als mein Programm fertig war, ließ mich denken, dass das Canvas-Update in einem anderen Thread ausgeführt wurde, der keine Priorität hatte.(Aber das wissen wir JavaScript ist Single-Threaded).

Meine Frage ist - Können wir einen requestAnimFrame als 'Ertrag' in der Anwendungsschleife betrachten, damit die Ereignisschleife verarbeitet werden kann? Kann ich trotzdem davon ausgehen, dass JavaScript Single-Threaded ist?

War es hilfreich?

Lösung

Sie wissen nicht genau, wie Sie Ihre Iteration 1000 Mal durchgeführt haben, aber ich nehme an, Sie meinen, Sie haben mit a iteriert for oder while schleife (?korrigiere mich, wenn ich falsch liege..).

Wenn Sie eine for / while-Schleife ausführen, wird das Skript so lange in einer Schleife ausgeführt, bis diese Schleife (oder dieser Bereich) abgeschlossen ist.Da JS, wie Sie wissen, Single-threaded ist, kann es währenddessen keine Dinge wie die Ereigniswarteschlange verarbeiten - daher kann nichts aktualisiert werden (inkl.DOM), bis die Schleife beendet ist (im Allgemeinen gibt es möglicherweise eine browserspezifische Implementierung, die DOM-Aktualisierungen zulässt, wenn DOM-Aktualisierungen beispielsweise in einem separaten Thread ausgeführt werden, dies ist jedoch eine andere Sache als JS).

Nachdem Sie nun rAF implementiert haben, führen Sie eine einzelne Iteration pro durch Rahmen.Dies bedeutet, dass der Browser Zeit hat, die Ereigniswarteschlange zu verarbeiten asynchron (nicht dasselbe wie Multithread) es sei denn, der Code, den Sie in der Schleife verarbeitet haben, hat auch eine Weile lang eine Busy-Schleife ausgeführt, wodurch dasselbe Szenario wie beim ersten erstellt würde.

Du hättest benutzen können setTimeout sowie.Was die rAF anders macht als zum Beispiel setTimeout oder setInterval ist es eine effiziente Low-Level-Implementierung eines Timer-Mechanismus, der in der Lage ist, sich mit dem des Monitors zu synchronisieren VBLANK periode (vertikale Austastung, die die Grafikkarte über eine Option namens vsync ausführt) - was im Klartext die Bildwiederholfrequenz des Monitors bedeutet (normalerweise 60 Hz).Dies ermöglicht es uns, glatte Animationen zu erstellen, und deshalb wird es request * Animation * Frame genannt, da es in erster Linie dafür gemacht ist.

Ist JS immer noch Single-Threaded?Ja, das wird sich nicht ändern (die einzige Möglichkeit, Multithreading in JS zu erreichen, ist die Verwendung von Web-Workern).

Ändert die rAF etwas?Nicht in diesem Bereich - es ist eine genauere und performantere Alternative zu setTimeout und es synchronisiert sich anders, aber das ist alles.Es wird den gleichen Einschränkungen unterliegen wie bei setTimeout kann nicht ausgelöst werden, wenn ein Bereich belegt ist (daher der request* teil des Namens, der keine Garantie impliziert), aber wenn er ausgelöst wird, wird er mit der Aktualisierungsrate des Monitors synchronisiert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top