Thanks to visit codestin.com
Credit goes to developer.mozilla.org

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

View in English Always switch to English

AbortSignal

Baseline Widely available *

This feature is well established and works across many devices and browser versions. It’s been available across browsers since ⁨April 2018⁩.

* Some parts of this feature may have varying levels of support.

Hinweis: Diese Funktion ist in Web Workers verfügbar.

Das AbortSignal-Interface repräsentiert ein Signalobjekt, das es Ihnen ermöglicht, mit einem asynchronen Vorgang (wie einer fetch-Anfrage) zu kommunizieren und diesen bei Bedarf über ein AbortController-Objekt abzubrechen.

EventTarget AbortSignal

Instanz-Eigenschaften

Erbt auch Eigenschaften von seinem übergeordneten Interface, EventTarget.

AbortSignal.aborted Schreibgeschützt

Ein Boolean, das angibt, ob die Anfrage bzw. die Anfragen, mit denen das Signal kommuniziert, abgebrochen ist/sind (true) oder nicht (false).

AbortSignal.reason Schreibgeschützt

Ein JavaScript-Wert, der den Abbruchgrund angibt, sobald das Signal abgebrochen wurde.

Statische Methoden

Erbt auch Methoden von seinem übergeordneten Interface, EventTarget.

AbortSignal.abort()

Gibt eine AbortSignal-Instanz zurück, die bereits als abgebrochen festgelegt ist.

AbortSignal.any()

Gibt ein AbortSignal zurück, das abbricht, wenn eines der gegebenen Abbruchsignale abbricht.

AbortSignal.timeout()

Gibt eine AbortSignal-Instanz zurück, die nach einer bestimmten Zeit automatisch abbricht.

Instanz-Methoden

Erbt auch Methoden von seinem übergeordneten Interface, EventTarget.

AbortSignal.throwIfAborted()

Wirft den Abbruch-reason des Signals, wenn das Signal abgebrochen wurde; andernfalls tut es nichts.

Ereignisse

Erbt auch Ereignisse von seinem übergeordneten Interface, EventTarget.

Dieses Ereignis kann mit addEventListener() gehört werden oder durch Zuweisen eines Ereignisbehandlers zur oneventname-Eigenschaft dieses Interfaces.

abort

Wird aufgerufen, wenn die asynchronen Vorgänge, mit denen das Signal kommuniziert, abgebrochen werden. Auch über die onabort-Eigenschaft verfügbar.

Beispiele

Abbrechen einer fetch-Operation mit einem expliziten Signal

Das folgende Beispiel zeigt, wie wir ein Signal verwenden könnten, um das Herunterladen eines Videos mit der Fetch-API abzubrechen.

Wir definieren zuerst eine Variable für unseren AbortController.

Vor jedem fetch-Request erstellen wir einen neuen Controller mit dem AbortController()-Konstruktor, dann holen wir eine Referenz zu seinem zugehörigen AbortSignal-Objekt mit der AbortController.signal-Eigenschaft.

Hinweis: Ein AbortSignal kann nur einmal verwendet werden. Nachdem es abgebrochen wurde, wird jeder fetch-Aufruf, der dasselbe Signal verwendet, sofort abgelehnt.

Wenn der fetch-Request initiiert wird, übergeben wir das AbortSignal als Option im Optionsobjekt der Anfrage (das { signal } unten). Dies verknüpft das Signal und den Controller mit der fetch-Anfrage und ermöglicht es uns, es abzubrechen, indem wir AbortController.abort() aufrufen, wie im zweiten Ereignislistener unten gezeigt.

Wenn abort() aufgerufen wird, lehnt das fetch()-Versprechen mit einer DOMException namens AbortError ab.

js
let controller;
const url = "video.mp4";

const downloadBtn = document.querySelector(".download");
const abortBtn = document.querySelector(".abort");

downloadBtn.addEventListener("click", fetchVideo);

abortBtn.addEventListener("click", () => {
  if (controller) {
    controller.abort();
    console.log("Download aborted");
  }
});

async function fetchVideo() {
  controller = new AbortController();
  const signal = controller.signal;

  try {
    const response = await fetch(url, { signal });
    console.log("Download complete", response);
    // process response further
  } catch (err) {
    console.error(`Download error: ${err.message}`);
  }
}

Wenn die Anfrage abgebrochen wird, nachdem der fetch()-Aufruf erfüllt wurde, aber bevor der Antworttext gelesen wurde, dann wird der Versuch, den Antworttext zu lesen, mit einer AbortError-Ausnahme abgelehnt.

js
async function get() {
  const controller = new AbortController();
  const request = new Request("https://example.org/get", {
    signal: controller.signal,
  });

  const response = await fetch(request);
  controller.abort();
  // The next line will throw `AbortError`
  const text = await response.text();
  console.log(text);
}

Sie finden ein voll funktionsfähiges Beispiel auf GitHub; Sie können es auch live sehen.

Abbrechen einer fetch-Operation mit einem Timeout

Wenn Sie die Operation bei einem Timeout abbrechen möchten, können Sie die statische Methode AbortSignal.timeout() verwenden. Diese gibt ein AbortSignal zurück, das nach einer bestimmten Anzahl von Millisekunden automatisch abläuft.

Der folgende Code-Schnipsel zeigt, wie Sie entweder erfolgreich eine Datei herunterladen oder einen Timeout-Fehler nach 5 Sekunden behandeln würden. Beachten Sie, dass bei einem Timeout das fetch()-Versprechen mit einer TimeoutError-DOMException abgelehnt wird. Dies ermöglicht es dem Code, zwischen Timeouts (für die wahrscheinlich eine Benutzerbenachrichtigung erforderlich ist) und Benutzerabbrüchen zu unterscheiden.

js
const url = "video.mp4";

try {
  const res = await fetch(url, { signal: AbortSignal.timeout(5000) });
  const result = await res.blob();
  // …
} catch (err) {
  if (err.name === "TimeoutError") {
    console.error("Timeout: It took more than 5 seconds to get the result!");
  } else if (err.name === "AbortError") {
    console.error(
      "Fetch aborted by user action (browser stop button, closing tab, etc.",
    );
  } else {
    // A network error, or some other problem.
    console.error(`Error: type: ${err.name}, message: ${err.message}`);
  }
}

Abbrechen einer fetch-Operation mit Timeout oder explizitem Abbruch

Wenn Sie von mehreren Signalen aus abbrechen möchten, können Sie AbortSignal.any() verwenden, um sie in ein einzelnes Signal zu kombinieren. Das folgende Beispiel zeigt dies mit fetch:

js
try {
  const controller = new AbortController();
  const timeoutSignal = AbortSignal.timeout(5000);
  const res = await fetch(url, {
    // This will abort the fetch when either signal is aborted
    signal: AbortSignal.any([controller.signal, timeoutSignal]),
  });
  const body = await res.json();
} catch (e) {
  if (e.name === "AbortError") {
    // Notify the user of abort.
  } else if (e.name === "TimeoutError") {
    // Notify the user of timeout
  } else {
    // A network error, or some other problem.
    console.log(`Type: ${e.name}, Message: ${e.message}`);
  }
}

Hinweis: Anders als bei der Verwendung von AbortSignal.timeout() gibt es keine Möglichkeit zu erkennen, ob der endgültige Abbruch aufgrund eines Timeouts verursacht wurde.

Implementierung einer abbrechbaren API

Eine API, die das Abbrechen unterstützen muss, kann ein AbortSignal-Objekt akzeptieren und seinen Zustand verwenden, um bei Bedarf das Signal zur Abbruchbehandlung auszulösen.

Eine API, die auf Promise basiert, sollte auf das Abbruchsignal reagieren, indem sie jedes ungesicherte Versprechen mit dem Abbruch-reason des AbortSignal ablehnt. Zum Beispiel können Sie die folgende myCoolPromiseAPI betrachten, die ein Signal annimmt und ein Versprechen zurückgibt. Das Versprechen wird sofort abgelehnt, wenn das Signal bereits abgebrochen ist oder das Abbruchereignis erkannt wird. Andernfalls wird es normal abgeschlossen und das Versprechen wird aufgelöst.

js
function myCoolPromiseAPI(/* …, */ { signal }) {
  return new Promise((resolve, reject) => {
    // If the signal is already aborted, immediately throw in order to reject the promise.
    if (signal.aborted) {
      reject(signal.reason);
      return;
    }

    // Perform the main purpose of the API
    // Call resolve(result) when done.

    // Watch for 'abort' signals
    signal.addEventListener("abort", () => {
      // Stop the main operation
      // Reject the promise with the abort reason.
      reject(signal.reason);
    });
  });
}

Die API könnte dann wie gezeigt verwendet werden. Beachten Sie, dass AbortController.abort() aufgerufen wird, um die Operation abzubrechen.

js
const controller = new AbortController();
const signal = controller.signal;

startSpinner();

myCoolPromiseAPI({ /* …, */ signal })
  .then((result) => {})
  .catch((err) => {
    if (err.name === "AbortError") return;
    showUserErrorMessage();
  })
  .then(() => stopSpinner());

controller.abort();

APIs, die keine Versprechen zurückgeben, könnten in ähnlicher Weise reagieren. In einigen Fällen kann es sinnvoll sein, das Signal zu absorbieren.

Spezifikationen

Specification
DOM
# interface-AbortSignal

Browser-Kompatibilität

Siehe auch