Websperren-API

Koordinieren Sie die Arbeit und den Einsatz von Ressourcen zwischen verschiedenen Prozessen

Zeit zum Einsperren

Asynchrone Funktionen in Javascript sind nicht wirklich parallel. Ab ES2017 unterstützt Javascript gleichzeitige Funktionsaufrufe. Den Unterschied fasst Madhavan Nagarajan im folgenden Statement sehr schön zusammen (Link findet sich im Addendum).

Bei der Parallelität geht es darum, viele Dinge gleichzeitig zu erledigen. Parallelität bedeutet, viele Dinge gleichzeitig zu tun.

Die Implementierung der Parallelität von Javascript ist in ihrer Funktionalität reduziert, um eine einfache und sehr robuste API zu verwenden. Asynchrone Funktionen können nicht unterbrochen werden und haben kein Konzept von flüchtigen Eigenschaften, wenn es um den Zugriff auf dieselbe Variable durch verschiedene asynchrone Aufrufe geht. Die detaillierte Implementierung der asynchronen Funktionen von ES2017 ist in diesem Artikel nicht enthalten, aber der Hauptpunkt, den ich vermitteln möchte, ist, dass bisher keine Parallelität in Javascript und das Web eingebaut war und daher keine spezielle Behandlung von parallelen Mutationen der gleiche Entität. Doch das ändert sich jetzt mit der Einführung der „Web Locks API“.

Einer für alle und alle für einen

Jetzt, da progressive Web-Apps Ihnen mit der Einführung von WebWorkern und dem ServiceWorker echte Multithread-Architekturen bieten, haben sich die Dinge geändert. Echte Parallelität ist in Web-Apps möglich, und daher entsteht der Wunsch nach ausgefeilteren Tools für den Umgang mit parallelem Code.

Eine Sperre ist ein Mechanismus, um Zugriff auf Ressourcen anzufordern und die Garantie zu haben, dass zu jedem Zeitpunkt nur ein Prozess wirklich Zugriff hat. Das Sperren von Ressourcen auf diese Weise vermeidet eine Vielzahl von Konfliktbereichen, die sonst entstehen könnten.

Eine Ressource ist nur ein Namespace, der durch eine Zeichenfolge identifiziert wird. Und Ihre Anfrage zum Zugriff auf die Ressource ist genauso einfach, da Sie nur die ID und einen wahrscheinlich asynchronen Funktionsrückruf benötigen, um die „Web Lock API“ zu implementieren. Wenn eine asynchrone Funktion beendet ist, wird die Sperre freigegeben und andere Anforderungen können wieder darauf zugreifen.

/*
 * A simple demonstration of the Web Lock API.
 * Note that this example has been taken from
 * MDN's awesome documentation, linked in the
 * addendum.
 */
async function foo(){
  // A common async function that you already know.
  const data = await getData();

  // Request the lock.
  // Note that we can simply await the locked call!
  await navigator.locks.request('lock_resource_id', async lock => {
    // The lock has been acquired.
    // At this point, this call has exlusive access 
    // to the resource 'lock_resource_id'.
    await updateDb(data);
    // Now the lock will be released.
  });
  
  // The lock has been released.
  // Continuse with plain async calls.
  await updateUi();
}

Aufgrund des experimentellen Status dieser neuen API müssen Sie sie als optionale Funktion in Ihrem Code mit einem verfügbaren gültigen Fallback behandeln.

/**
 * Due to the usage of web locks in core parts
 * of your app, actually using the API this way
 * might introduce more problems then it could solve.
 * 
 * Therefore a thorough specification in your app
 * has to be implementation before using this feature.
 */
async function update(){
  if(navigator?.locks){
    // Run logic with lock.
  } else {
    // Use fallback.
  }
}

Um diese neue API besser zu veranschaulichen, sehen wir uns ein einfaches Beispiel an. Angenommen, Sie haben eine Multithread-PWA mit Ihrem Hauptprozess und zwei WebWorkern. Ihre App verwendet auch eine IndexDB mit benutzerdefiniertem Code, der Änderungen an und von der Datenbank mit der Cloud synchronisiert. Mit der „Web Lock API“ kann in diesem Szenario jeder Prozess Zugriff auf die definierte Sperre anfordern, um Änderungen mit der Datenbank zu synchronisieren, um sicherzustellen, dass während dieses Aufrufs keine anderen Mutationen ausgeführt werden.

Beachten Sie, dass es bei der „Web Lock API“ nicht so sehr darum geht, eine einzelne Variable ohne Nebenwirkungen in Ihrer Web-App zu mutieren (obwohl dies eindeutig ein Anwendungsfall sein kann), sondern eher um die Handhabung von Funktionsaufrufen in einer parallelen Architektur, die sonst zu negative Nebenwirkungen.

Viel mehr zu lernen

Dieser Artikel gab nur eine Einführung in die neue "Web Locks API", die sich derzeit im experimentellen Status befindet und hauptsächlich von Chromium-basierten Browsern unterstützt wird. Die API bietet weitere Optionen, die hier beschrieben werden und ist einen Blick wert.