[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Execution_model#run-to-completion [Back]  [Original]

JavaScript-Ausfhrungsmodell - JavaScript | MDN

Dieser Inhalt wurde automatisch aus dem Englischen bersetzt, und kann Fehler enthalten. Erfahre mehr ber dieses Experiment.

View in English Always switch to English

JavaScript-Ausfhrungsmodell

Diese Seite fhrt in die grundlegende Infrastruktur der JavaScript-Laufzeitumgebung ein. Das Modell ist grtenteils theoretisch und abstrakt, ohne plattform- oder implementierungs-spezifische Details. Moderne JavaScript-Engines optimieren die beschriebenen Semantiken stark.

Diese Seite ist eine Referenz. Sie setzt voraus, dass Sie bereits mit dem Ausfhrungsmodell anderer Programmiersprachen wie C und Java vertraut sind. Sie bezieht sich stark auf bestehende Konzepte in Betriebssystemen und Programmiersprachen.

In diesem Artikel

Die Engine und der Host

Fr die Ausfhrung von JavaScript ist die Zusammenarbeit von zwei Software-Komponenten erforderlich: der JavaScript-Engine und die Host-Umgebung.

Die JavaScript-Engine implementiert die ECMAScript (JavaScript) Sprache, welche die Kernfunktionalitt bereitstellt. Sie nimmt Quellcode, analysiert ihn und fhrt ihn aus. Um jedoch mit der Auenwelt zu interagieren, beispielsweise um aussagekrftige Ausgaben zu erzeugen, externe Ressourcen zu nutzen oder sicherheits- oder leistungsbezogene Mechanismen zu implementieren, bentigen wir zustzliche, umgebungsspezifische Mechanismen, die von der Host-Umgebung bereitgestellt werden. Zum Beispiel ist der HTML DOM die Host-Umgebung, wenn JavaScript in einem Webbrowser ausgefhrt wird. Node.js ist eine weitere Host-Umgebung, die es JavaScript ermglicht, serverseitig ausgefhrt zu werden.

Whrend wir uns in dieser Referenz hauptschlich auf die in ECMAScript definierten Mechanismen konzentrieren, werden wir gelegentlich ber Mechanismen sprechen, die in der HTML-Spezifikation definiert sind und oft von anderen Host-Umgebungen wie Node.js oder Deno nachgeahmt werden. So knnen wir ein kohrentes Bild des JavaScript-Ausfhrungsmodells geben, wie es im Web und darber hinaus verwendet wird.

Agenten-Ausfhrungsmodell

In der JavaScript-Spezifikation wird jeder autonome JavaScript-Ausfhrer als Agent bezeichnet, der seine eigenen Mittel zur Ausfhrung von Code unterhlt:

  • Heap (von Objekten): Dies ist nur ein Name fr einen groen (meist unstrukturierten) Speicherbereich. Er wird gefllt, wenn Objekte im Programm erstellt werden. Beachten Sie, dass im Falle einer gemeinsamen Speicherverwendung jeder Agent seinen eigenen Heap mit seiner eigenen Version eines SharedArrayBuffer-Objekts hat, der zugrundeliegende Speicher, der durch den Buffer dargestellt wird, jedoch gemeinsam genutzt wird.
  • Warteschlange (von Jobs): Dies ist in HTML (und blicherweise) bekannt als die Ereignisschleife, die asynchrones Programmieren in JavaScript ermglicht, whrend es doch single-threaded bleibt. Es wird als Warteschlange bezeichnet, weil es im Allgemeinen ein First-in-First-out ist: frhere Jobs werden vor spteren ausgefhrt.
  • Stapel (von Ausfhrungskontexten): Dies ist das, was als Aufrufstapel bekannt ist und die Steuerflussbertragung durch Eingeben und Verlassen von Ausfhrungskontexten wie Funktionen ermglicht. Es wird als Stapel bezeichnet, da es ein Last-in-First-out ist. Jeder Job beginnt durch Hinzufgen eines neuen Frames auf den (leeren) Stapel und endet, wenn der Stapel geleert wird.

Dies sind drei verschiedene Datenstrukturen, die unterschiedliche Daten im Auge behalten. Wir werden die Warteschlange und den Stapel in den folgenden Abschnitten genauer vorstellen. Um mehr darber zu lesen, wie Speicherplatz im Heap zugewiesen und freigegeben wird, lesen Sie Speicherverwaltung.

Jeder Agent ist analog zu einem Thread (beachten Sie, dass die zugrunde liegende Implementierung mglicherweise nicht tatschlich ein Betriebssystem-Thread ist). Jeder Agent kann mehrere Realm besitzen (die 1-zu-1 mit globalen Objekten korrelieren), die sich gegenseitig synchron aufrufen knnen und dadurch in einem einzelnen Ausfhrungsthread laufen mssen. Ein Agent hat auch ein einzelnes Speicher-Modell, das angibt, ob es little-endian ist, ob es synchron blockiert werden kann, ob atomare Operationen sperrfrei sind, etc.

Ein Agent im Web kann eine der folgenden Formen annehmen:

Mit anderen Worten, jeder Arbeiter erstellt seinen eigenen Agenten, whrend eines oder mehrere Fenster im selben Agent sein knnennormalerweise ein Hauptdokument und seine hnlichen Ursprungs-Iframes. In Node.js steht ein hnliches Konzept namens worker threads zur Verfgung.

Das nachstehende Diagramm illustriert das Ausfhrungsmodell von Agenten:

Ein Diagramm, das aus zwei Agenten besteht: eine HTML-Seite und ein Worker. Jeder hat seinen eigenen Stapel mit Ausfhrungskontexten, Heap mit Objekten und Warteschlange mit Jobs. [Ein Diagramm, das aus zwei Agenten besteht: eine HTML-Seite und ein Worker. Jeder hat seinen eigenen Stapel mit Ausfhrungskontexten, Heap mit Objekten und Warteschlange mit Jobs.]

Realms

Jeder Agent besitzt ein oder mehrere Realms. Jedes Stck JavaScript-Code ist einem Realm zugeordnet, wenn es geladen wird, der gleich bleibt, selbst wenn er von einem anderen Realm aus aufgerufen wird. Ein Realm besteht aus den folgenden Informationen:

  • Eine Liste von intrinsischen Objekten wie Array, Array.prototype, usw.
  • Global deklarierte Variablen, der Wert von globalThis und das globale Objekt
  • Ein Cache von Template-Literal-Arrays, da die Auswertung des gleichen getaggten Template-Literal-Ausdrucks immer dazu fhrt, dass der Tag dasselbe Array-Objekt erhlt

Im Web korrespondieren das Realm und das globale Objekt 1-zu-1. Das globale Objekt ist entweder ein Window, ein WorkerGlobalScope oder ein WorkletGlobalScope. Zum Beispiel fhrt jedes iframe in einem anderen Realm aus, obwohl es sich im selben Agenten wie das bergeordnete Fenster befinden kann.

Realms werden normalerweise erwhnt, wenn es um die Identitten globaler Objekte geht. Zum Beispiel bentigen wir Methoden wie Array.isArray() oder Error.isError(), weil ein Array, das in einem anderen Realm konstruiert wurde, ein anderes Prototypobjekt als das Array.prototype-Objekt im derzeitigen Realm hat, sodass instanceof Array flschlicherweise false zurckgeben wrde.

Stapel und Ausfhrungskontexte

Wir betrachten zuerst die synchrone Code-Ausfhrung. Jeder Job startet mit dem Aufruf seines zugehrigen Callbacks. Code innerhalb dieses Callback kann Variablen erstellen, Funktionen aufrufen oder enden. Jede Funktion muss ihre eigenen Variablendeklarationen und den Rcksprungpunkt speichern. Um dies zu handhaben, bentigt der Agent einen Stapel, um die Ausfhrungskontexte zu verfolgen. Ein Ausfhrungskontext, auch allgemein als Stapelrahmen bekannt, ist die kleinste Ausfhrungseinheit. Er verfolgt die folgenden Informationen:

  • Status der Codeauswertung
  • Das Modul oder das Skript, die Funktion (falls zutreffend) und der aktuell ausfhrende Generator, der diesen Code enthlt
  • Der aktuelle Realm
  • Bindings, einschlielich:
    • Variablen, die mit var, let, const, function, class usw. definiert sind
    • Private Bezeichner wie #foo, die nur im aktuellen Kontext gltig sind
    • this-Referenz

Stellen Sie sich ein Programm vor, das aus einem einzelnen Job besteht, der durch den folgenden Code definiert ist:

js
function foo(b) {
  const a = 10;
  return a + b + 11;
}

function bar(x) {
  const y = 3;
  return foo(x * y);
}

const baz = bar(7); // assigns 42 to baz
  1. Wenn der Job startet, wird der erste Frame erstellt, in dem die Variablen foo, bar und baz definiert werden. Er ruft bar mit dem Argument 7 auf.
  2. Ein zweiter Frame wird fr den bar-Aufruf erstellt, der Bindungen fr den Parameter x und die lokale Variable y enthlt. Zuerst fhrt er die Multiplikation x * y aus und ruft dann foo mit dem Ergebnis auf.
  3. Ein dritter Frame wird fr den foo-Aufruf erstellt, der Bindungen fr den Parameter b und die lokale Variable a enthlt. Zuerst fhrt er die Addition a + b + 11 aus und gibt dann das Ergebnis zurck.
  4. Wenn foo zurckgibt, wird das oberste Element des Stapelrahmens entfernt, und der Aufrufausdruck foo(x * y) wird in den Rckgabewert aufgelst. Es wird dann mit der Ausfhrung fortgesetzt, was darin besteht, dieses Ergebnis zurckzugeben.
  5. Wenn bar zurckgibt, wird das oberste Element des Stapelrahmens entfernt, und der Aufrufausdruck bar(7) wird in den Rckgabewert aufgelst. Dies initialisiert baz mit dem Rckgabewert.
  6. Wir erreichen das Ende des Quellcodes des Jobs, sodass der Stapelrahmen fr den Einstiegspunkt aus dem Stapel entfernt wird. Der Stapel ist leer, sodass der Job als abgeschlossen betrachtet wird.

Generatoren und Wiedereintritt

Wenn ein Frame entfernt wird, ist er nicht unbedingt fr immer verschwunden, denn manchmal mssen wir zu ihm zurckkehren. Betrachten Sie zum Beispiel eine Generatorfunktion:

js
function* gen() {
  console.log(1);
  yield;
  console.log(2);
}

const g = gen();
g.next(); // logs 1
g.next(); // logs 2

In diesem Fall erstellt der Aufruf von gen() zuerst einen Ausfhrungskontext, der angehalten wirdkein Code innerhalb von gen wird bis jetzt ausgefhrt. Der Generator g speichert diesen Ausfhrungskontext intern. Der aktuell laufende Ausfhrungskontext bleibt der Einstiegspunkt. Wenn g.next() aufgerufen wird, wird der Ausfhrungskontext fr gen auf den Stapel geschoben und der Code innerhalb von gen wird bis zum yield-Ausdruck ausgefhrt. Dann wird der Ausfhrungskontext des Generators angehalten und aus dem Stapel entfernt, was die Kontrolle zurck an den Einstiegspunkt gibt. Wenn g.next() erneut aufgerufen wird, wird der Ausfhrungskontext des Generators wieder auf den Stapel geschoben und der Code innerhalb von gen wird dort fortgesetzt, wo er aufgehrt hat.

Tail Calls

Ein Mechanismus, der in der Spezifikation definiert ist, ist der proper tail call (PTC). Ein Funktionsaufruf ist ein Tail Call, wenn der Aufrufer nach dem Aufruf nichts anderes tut, als den Wert zurckzugeben:

js
function f() {
  return g();
}

In diesem Fall ist der Aufruf von g ein Tail Call. Wenn ein Funktionsaufruf in Tail-Position ist, wird die Engine angewiesen, den aktuellen Ausfhrungskontext zu verwerfen und ihn durch den Kontext des Tail Calls zu ersetzen, anstelle eines neuen Frames fr den g()-Aufruf. Dies bedeutet, dass Tail-Rekursion nicht den Stapelgrenbeschrnkungen unterliegt:

js
function factorial(n, acc = 1) {
  if (n <= 1) return acc;
  return factorial(n - 1, n * acc);
}

In der Praxis verursacht das Verwerfen des aktuellen Frames Debugging-Probleme, denn wenn g() einen Fehler wirft, ist f nicht mehr im Stapel und erscheint nicht im Stack-Trace. Derzeit implementiert nur Safari (JavaScriptCore) PTC, und sie haben einige spezielle Infrastruktur erfunden, um dieses Debugging-Problem zu lsen.

Closures

Ein weiteres interessantes Phnomen im Zusammenhang mit Variablen-Bereich und Funktionsaufrufen sind Closures. Wann immer eine Funktion erstellt wird, merkt sie sich auch die Variablenbindungen des aktuell laufenden Ausfhrungskontexts intern. Dann knnen diese Variablenbindungen den Ausfhrungskontext berdauern.

js
let f;
{
  let x = 10;
  f = () => x;
}
console.log(f()); // logs 10

Aufgabenwarteschlange und Ereignisschleife

Ein Agent ist ein Thread, was bedeutet, dass der Interpreter nur eine Anweisung auf einmal verarbeiten kann. Wenn der Code vollstndig synchron ist, ist dies in Ordnung, da wir immer Fortschritte machen knnen. Aber wenn der Code asynchrone Aktionen durchfhren muss, dann knnen wir nicht weiter machen, es sei denn, diese Aktion ist abgeschlossen. Es wre jedoch fr die Benutzererfahrung nachteilig, wenn das das gesamte Programm anhalten wrdedie Natur von JavaScript als Web-Skriptsprache erfordert, dass es niemals blockiert. Daher wird der Code, der die Fertigstellung dieser asynchronen Aktion verarbeitet, als Callback definiert. Dieses Callback definiert einen Job, der in eine Aufgabenwarteschlangeoder in HTML-Begriffen, eine Ereignisschleifenach Abschluss der Aktion gesetzt wird.

Jedes Mal zieht der Agent einen Job aus der Warteschlange und fhrt ihn aus. Wenn der Job ausgefhrt wird, kann er weitere Jobs erstellen, die am Ende der Warteschlange hinzugefgt werden. Jobs knnen auch durch den Abschluss asynchroner Plattformmechanismen wie Timer, I/O und Ereignisse hinzugefgt werden. Ein Job wird als abgeschlossen betrachtet, wenn der Stapel leer ist; dann wird der nchste Job aus der Warteschlange gezogen. Die Jobs knnen mglicherweise nicht mit gleichmiger Prioritt ausgefhrt werdenzum Beispiel teilen HTML-Ereignisschleifen Jobs in zwei Kategorien auf: Aufgaben und Mikroaufgaben. Mikroaufgaben haben eine hhere Prioritt und die Mikroaufgaben-Warteschlange wird zuerst geleert, bevor die Aufgaben-Warteschlange aufgerufen wird. Fr weitere Informationen lesen Sie den HTML-Mikroaufgaben-Leitfaden. Wenn die Arbeitswarteschlange leer ist, wartet der Agent, bis weitere Jobs hinzugefgt werden.

"Run-to-completion"

Jeder Job wird vollstndig verarbeitet, bevor ein anderer Job verarbeitet wird. Dies bietet einige nette Eigenschaften bei der Argumentation ber Ihr Programm, einschlielich der Tatsache, dass, wenn eine Funktion ausgefhrt wird, sie nicht unterbrochen werden kann und vollstndig ausgefhrt wird, bevor ein anderer Code ausgefhrt wird (und Daten, mit denen die Funktion arbeitet, gendert werden knnen). Dies unterscheidet sich von C, wo, wenn eine Funktion in einem Thread luft, sie an jedem Punkt vom Laufzeitsystem angehalten werden kann, um einen anderen Code in einem anderen Thread auszufhren.

Zum Beispiel, betrachten Sie dieses Beispiel:

js
const promise = Promise.resolve();
let i = 0;
promise.then(() => {
  i += 1;
  console.log(i);
});
promise.then(() => {
  i += 1;
  console.log(i);
});

In diesem Beispiel erstellen wir ein bereits aufgelstes Promise, was bedeutet, dass jeder angefgte Callback sofort als Jobs eingeplant wird. Die beiden Callbacks scheinen eine Race-Bedingung zu verursachen, aber tatschlich ist die Ausgabe vollstndig vorhersehbar: 1 und 2 werden in Reihenfolge protokolliert. Dies liegt daran, dass jeder Job vollstndig ausgefhrt wird, bevor der nchste gestartet wird, sodass die Gesamtreihenfolge immer i += 1; console.log(i); i += 1; console.log(i); und niemals i += 1; i += 1; console.log(i); console.log(i); ist.

Ein Nachteil dieses Modells ist, dass, wenn ein Job zu lange braucht, um abgeschlossen zu werden, die Webanwendung nicht in der Lage ist, Benutzerinteraktionen wie Klicken oder Scrollen zu verarbeiten. Der Browser mildert dies mit dem Dialog "Ein Skript luft zu lange". Eine gute Praxis ist, die Bearbeitung von Jobs kurz zu halten und, wenn mglich, einen Job in mehrere Jobs zu unterteilen.

Niemals blockieren

Ein weiteres wichtiges Versprechen des Ereignisschleifenmodells ist, dass die JavaScript-Ausfhrung niemals blockiert. Die Behandlung von Eingabe/Ausgabe wird normalerweise ber Ereignisse und Callbacks durchgefhrt, sodass die Anwendung, whrend sie auf eine Antwort einer IndexedDB-Abfrage oder einen fetch()-Anfrage wartet, weiterhin andere Dinge wie Benutzereingaben verarbeiten kann. Der Code, der nach der Fertigstellung einer asynchronen Aktion ausgefhrt wird, wird immer als Callback-Funktion bereitgestellt (zum Beispiel, der Promise then()-Handler, die Callback-Funktion in setTimeout() oder der Ereignis-Handler), was einen Job definiert, der in die Aufgabenschlange eingefgt wird, sobald die Aktion beendet ist.

Natrlich erfordert das Versprechen "niemals blockieren", dass die Plattform-API inhrent asynchron ist, aber einige veraltete Ausnahmen existieren, wie alert() oder synchrones XHR. Es wird als gute Praxis angesehen, diese zu vermeiden, um die Reaktionsfhigkeit der Anwendung sicherzustellen.

Agenten-Cluster und gemeinsame Speicherverwendung

Mehrere Agenten knnen ber die gemeinsame Nutzung von Speicher kommunizieren und bilden dabei einen Agenten-Cluster. Agenten befinden sich im selben Cluster, wenn und nur wenn sie Speicher teilen knnen. Es gibt keinen eingebauten Mechanismus, damit zwei Agenten-Cluster Informationen austauschen knnen, sodass sie als vollstndig isolierte Ausfhrungsmodelle angesehen werden knnen.

Beim Erstellen eines Agenten (wie zum Beispiel durch das Starten eines Workers), gibt es einige Kriterien dafr, ob er sich im selben Cluster wie der aktuelle Agent befindet oder ob ein neuer Cluster erstellt wird. Zum Beispiel gehren die folgenden Paare von globalen Objekten jeweils zum selben Agenten-Cluster und knnen daher Speicher miteinander teilen:

  • Ein Window-Objekt und ein dedizierter Worker, den es erstellt hat.
  • Ein Worker (von jedem Typ) und ein dedizierter Worker, den es erstellt hat.
  • Ein Window-Objekt A und das Window-Objekt eines Ursprungs-iframe-Objekts, das A erstellt hat.
  • Ein Window-Objekt und ein Ursprungs-Window-Objekt, das es geffnet hat.
  • Ein Window-Objekt und ein Worklet, das es erstellt hat.

Die folgenden Paare von globalen Objekten gehren nicht zum selben Agenten-Cluster und knnen daher keinen Speicher teilen:

  • Ein Window-Objekt und ein gemeinsam genutzter Worker, den es erstellt hat.
  • Ein Worker (von jedem Typ) und ein gemeinsam genutzter Worker, den es erstellt hat.
  • Ein Window-Objekt und ein Service-Worker, den es erstellt hat.
  • Ein Window-Objekt A und das Window-Objekt eines iframe-Elements, das A erstellt hat, das nicht denselben Ursprungsbereich wie A haben kann.
  • Beliebige zwei Window-Objekte ohne ffner oder Vorfahren-Beziehung. Dies gilt auch dann, wenn die beiden Window-Objekte denselben Ursprungswert haben.

Fr den genauen Algorithmus siehe die HTML-Spezifikation.

Kommunikation zwischen Agenten und Speicher-Modell

Wie bereits erwhnt, kommunizieren Agenten ber die gemeinsame Nutzung von Speicher. Im Web wird Speicher ber die Methode postMessage() geteilt. Der Leitfaden zur Verwendung von Web-Workern bietet einen berblick darber. Typischerweise werden Daten nur durch Wert bergeben (durch strukturierte Duplizierung) und beinhalten daher keine Probleme mit der Nebenlufigkeit. Um Speicher zu teilen, muss ein SharedArrayBuffer-Objekt gepostet werden, das von mehreren Agenten gleichzeitig verwendet werden kann. Sobald zwei Agenten Zugriff auf denselben Speicher ber einen SharedArrayBuffer teilen, knnen sie die Ausfhrungen ber das Atomics-Objekt synchronisieren.

Es gibt zwei Mglichkeiten, auf den gemeinsamen Speicher zuzugreifen: ber normale Speicherzugriffe (die nicht atomar sind) und ber atomare Speicherzugriffe. Letztere sind sequentiell konsistent (das bedeutet, dass es eine strenge Gesamtordnung von Ereignissen gibt, auf die sich alle Agenten im Cluster einigen), whrend die erstere ungeordnet ist (das bedeutet, dass es keine Ordnung gibt); JavaScript bietet keine Operationen mit anderen Ordnungsversprechen.

Die Spezifikation gibt die folgenden Richtlinien fr Programmierer, die mit gemeinsamem Speicher arbeiten:

Wir empfehlen, Programme rennbedingungsfrei zu halten, d.h. sicherzustellen, dass es unmglich ist, dass nicht-atomare Vorgnge gleichzeitig auf derselben Speicherstelle stattfinden. Rennbedingungsfreie Programme haben Verflechtungssemantiken, bei denen jeder Schritt in der Evaluierungssemantik jedes Agenten untereinander verflochten ist. Fr rennbedingungsfreie Programme ist es nicht notwendig, die Details des Speicher-Modells zu verstehen. Die Details werden wahrscheinlich keine Intuition vermitteln, die dabei hilft, ECMAScript besser zu schreiben.

Allgemeiner gesagt, auch wenn ein Programm nicht rennbedingungsfrei ist, kann es vorhersehbares Verhalten haben, solange atomare Vorgnge nicht in Races involviert sind und die Vorgnge, die in Races involviert sind, alle dieselbe Zugriffsgre haben. Der einfachste Weg, um sicherzustellen, dass Atomics nicht in Rennen verwickelt sind, besteht darin, sicherzustellen, dass unterschiedliche Speicherzellen von atomaren und nicht-atomaren Vorgngen verwendet werden und dass atomare Zugriffe unterschiedlicher Gren nicht gleichzeitig auf dieselben Zellen zugreifen. Effektiv sollte das Programm versuchen, den gemeinsam genutzten Speicher so stark wie mglich typisiert zu behandeln. Man kann sich immer noch nicht auf die Ordnung und das Timing von nicht-atomaren Zugriffen, die in Rennen stehen, verlassen, aber wenn Speicher stark typisiert behandelt wird, werden die rennbedingten Zugriffe nicht "zerreien" (Teile ihrer Werte werden nicht durchgemischt).

Nebenlufigkeit und Sicherstellung von Fortschritten

Wenn mehrere Agenten zusammenarbeiten, gilt das Versprechen des niemals blockierenden nicht immer. Ein Agent kann blockiert oder pausiert werden, whrend er darauf wartet, dass ein anderer Agent eine Aktion durchfhrt. Dies unterscheidet sich von einem Warten auf ein Versprechen im selben Agenten, da es den gesamten Agenten stoppt und keinen anderen Code in der Zwischenzeit ausfhren lsstin anderen Worten, es kann keine Fortschritte machen.

Um Deadlocks zu verhindern, gibt es starke Einschrnkungen, wann und welche Agenten blockiert werden knnen.

  • Jeder nicht blockierte Agent mit einem dedizierten ausfhrenden Thread macht schlielich Fortschritte.
  • In einer Gruppe von Agenten, die einen ausfhrenden Thread teilen, macht schlielich ein Agent Fortschritte.
  • Ein Agent verursacht keinen anderen Agenten, blockiert zu werden, auer ber explizite APIs, die das Blockieren ermglichen.
  • Nur bestimmte Agenten knnen blockiert werden. Im Web sind dies dedizierte Worker und gemeinsam genutzte Worker, jedoch nicht hnlich-ursprungsbasierte Fenster oder Service-Worker.

Der Agenten-Cluster sorgt fr ein gewisses Ma an Integritt ber die Aktivitt seiner Agenten im Falle externer Pausen oder Beendigungen:

  • Ein Agent kann ohne sein Wissen oder Einverstndnis angehalten oder fortgesetzt werden. Zum Beispiel kann das Navigieren weg von einem Fenster die Code-Ausfhrung aussetzen, aber seinen Zustand bewahren. Ein Agenten-Cluster darf jedoch nicht teilweise deaktiviert sein, um zu vermeiden, dass ein Agent verhungert, weil ein anderer Agent deaktiviert wurde. Zum Beispiel sind gemeinsam genutzte Worker niemals im gleichen Agenten-Cluster wie das erzeugende Fenster oder andere dedizierte Worker. Dies liegt daran, dass die Lebensdauer eines gemeinsam genutzten Workers unabhngig von Dokumenten ist: Wenn ein Dokument deaktiviert wird, whrend sein dedizierter Worker einen Lock hlt, wird der gemeinsam genutzte Worker daran gehindert, den Lock zu erwerben, bis der dedizierte Worker wieder aktiviert wird, wenn berhaupt. In der Zwischenzeit verhungern andere Worker, die versuchen, ber andere Fenster auf den gemeinsam genutzten Worker zuzugreifen.
  • Ebenso kann ein Agent von Faktoren auerhalb des Clusters beendet werden. Zum Beispiel durch Betriebssysteme oder Benutzer, die einen Browser-Prozess tten, oder den Browser, der einen Agenten zwangsweise beendet, weil er zu viele Ressourcen verbraucht. In diesem Fall werden alle Agenten im Cluster beendet. (Die Spezifikation erlaubt auch eine zweite Strategie, die darin besteht, eine API bereitzustellen, die es ermglicht, dass mindestens ein verbleibendes Mitglied des Clusters die Beendigung und den Agenten zu identifizieren, der beendet wurde, aber dies ist im Web nicht implementiert.)

Spezifikationen

Spezifikation
ECMAScript 2027 LanguageSpecification
ECMAScript 2027 LanguageSpecification
HTML

Siehe auch


Web Proxy Viewer  |  New URL  |  Original Page