it-swarm.com.de

Was bestimmt, welche Javascript-Funktionen blockieren oder welche nicht?

Ich mache seit einigen Jahren webbasiertes Javascript (Vanilla JS, jQuery, Backbone usw.) und habe kürzlich mit Node.js gearbeitet. Es hat eine Weile gedauert, bis ich mich mit der "nicht blockierenden" Programmierung vertraut gemacht hatte, aber jetzt habe ich mich daran gewöhnt, Rückrufe für IO Operationen und so weiter) zu verwenden.

Ich verstehe, dass Javascript von Natur aus Single-Threaded ist. Ich verstehe das Konzept der Node "Ereigniswarteschlange". Was ich nicht verstehe, ist, was bestimmt, ob eine einzelne Javascript-Operation "blockiert" oder "nicht blockiert". Wie gehe ich vor? Wissen, auf welche Operationen ich mich verlassen kann, um eine Ausgabe synchron zu erstellen, damit ich sie in späterem Code verwenden kann, und an welche ich Rückrufe weiterleiten muss, damit ich die Ausgabe nach Abschluss der ersten Operation verarbeiten kann? Gibt es eine Liste mit Javascript? Funktionen irgendwo, die asynchron/nicht blockierend sind, und eine Liste von solchen, die synchron/blockierend sind? Was hindert meine Javascript-App daran, eine riesige Rennbedingung zu sein?

Ich weiß, dass Operationen, die lange dauern, wie IO Operationen in Node und AJAX Operationen im Web), erfordern Sie sollen asynchron sein und daher Rückrufe verwenden - aber wer bestimmt, was als "lange Zeit" zu qualifizieren ist? Gibt es eine Art Auslöser in diesen Vorgängen, der sie aus der normalen "Ereigniswarteschlange" entfernt? Wenn nicht, was unterscheidet sie von einfache Operationen wie das Zuweisen von Werten zu Variablen oder das Durchlaufen von Arrays, auf die wir uns anscheinend verlassen können, um synchron fertig zu werden?

Vielleicht denke ich nicht einmal richtig darüber nach - in der Hoffnung, dass mich jemand klarstellen kann. Vielen Dank!

27
Sean

Im Allgemeinen ist jede Funktion, die über einen bestimmten Zeitraum Netzwerk- oder Timer-Aufgaben ausführt, asynchron.

Wenn die Funktion einen Rückruf entgegennimmt, können Sie sich ansehen, wofür der Rückruf verwendet wird. In der Regel ist es offensichtlich, ob er asynchron ist oder nicht. Wenn die Funktion keinen Rückruf bietet, kann sie keine asynchronen Ergebnisse übertragen, sodass sie wahrscheinlich nicht asynchron ist.

Es gibt keine eiserne Möglichkeit, dies sicher zu sagen. Es muss entweder im Dokument für eine Funktion angegeben oder anhand der Funktionsweise der Benutzeroberfläche ersichtlich sein.

Asynchrone Operationen unterscheiden sich unter dem Deckmantel von synchronen Operationen darin, dass asynchrone Operationen den Gedanken haben, eine Operation einzurichten, die Operation zu starten und später über Fortschritt, Abschluss oder Fehler in der Operation informiert zu werden. Das Iterieren eines Arrays ist eine synchrone Operation. Es hat keines dieser Probleme. Der Code läuft nur synchron. Das Ausgeben eines Ajax-Aufrufs besteht darin, einen Rückruf für Statusbenachrichtigungen zu registrieren, dann den Ajax-Aufruf zu starten, dann ein anderes Javascript auszuführen und einige Zeit später den Rückruf mit einer Statusänderung beim Ajax-Aufruf (z. B. Abschluss) aufzurufen.

13
jfriend00

Soweit ich weiß, fragen Sie nicht, was Sie asynchron machen soll, sondern wie Sie feststellen können, ob eine Funktion asynchron ist.

Sie überprüfen die Dokumentation. Im Ernst - dafür ist es da. Sie raten nicht, was eine Funktion aufgrund ihres Namens oder ihres Kontexts einfach so macht. Wenn Sie sich nicht sicher sind und Zugriff auf den Quellcode haben, überprüfen Sie dies.

Das ist der einzig absolut zuverlässige Weg.

Nun zur Vermutung.

  • Wenn es einen Rückruf akzeptiert oder ein Versprechen zurückgibt, ist es wahrscheinlich asynchron (ich habe Ausnahmen für diese Regel gesehen).
  • Im Allgemeinen wird alles, was in node.js und allgemeiner in JavaScript mit E/A zusammenhängt, asynchron ausgeführt (ich habe auch Ausnahmen von dieser Regel gesehen).
6

Da JavaScript Single-Threaded ist, werden alle Verarbeitungsblöcke bis zu einem der folgenden Schritte ausgeführt

1) Die aktuelle Ausführung fordert einen externen Dienst an, z. B. eine E/A- oder Netzwerkanforderung oder eine Webworker-Anforderung

2) Ein Funktionsaufruf wird an einen Timer gesendet, der zu einem späteren Zeitpunkt ausgeführt wird

Es gibt keine Liste blockierender/nicht blockierender Funktionen. Sie sollten die Dokumentation überprüfen.

Ihre App kann auf eine Race-Bedingung stoßen, wenn mehrere externe Dienste den Javascript-Thread sperren und gleichzeitig versuchen, darauf zuzugreifen. Moderne Browser und die V8-Engine übernehmen dies, aber Sie können auf diese Rennbedingung stoßen, wenn Sie Phonegap verwenden und Javascript-Apps für mobile Geräte schreiben. Die Unterstützung ist nicht da, um diese Rennbedingungen zu bewältigen.

Nehmen Sie im Allgemeinen die Codeblöcke an, es sei denn, es liegt ein Rückruf vor. Und selbst wenn es einen Rückruf gibt, heißt das nicht, dass er nicht blockiert wird.

4
coder