Start · Sprachen · JavaScript · Referenz · FileReader: abort

FileReader: abort

Ereignis

Wird ausgelöst, wenn ein Lesevorgang eines <code>FileReader</code> abgebrochen wurde, etwa durch einen Aufruf von <code>FileReader.abort()</code>.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

reader.addEventListener("abort", handler)

Beschreibung

Das abort-Ereignis des FileReader-Interfaces wird ausgelöst, wenn ein laufender Lesevorgang abgebrochen wird. Meistens liegt das daran, dass das Programm selbst FileReader.abort() aufgerufen hat, zum Beispiel weil der Benutzer auf „Abbrechen“ geklickt hat oder eine andere Datei ausgewählt wurde.

Du kannst den Handler über addEventListener("abort", handler) registrieren oder über die Eigenschaft reader.onabort = handler zuweisen. Der Handler bekommt ein ProgressEvent mit den Eigenschaften loaded, total und lengthComputable. Daran lässt sich ablesen, wie weit der Lesevorgang vor dem Abbruch gekommen war.

Die Reihenfolge der Ereignisse bei einem Abbruch lautet: abort und danach loadend. Ein load- oder error-Ereignis gibt es in diesem Fall nicht. Nach dem Abbruch ist reader.readyState auf FileReader.DONE (2) gesetzt und reader.result ist null. Aufräumarbeiten, die nach jedem Ende nötig sind (etwa einen Ladeindikator ausblenden), gehören daher besser in loadend. Das abort-Ereignis eignet sich für Logik, die nur beim Abbruch laufen soll.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "abort".
$handler Pflicht (event: ProgressEvent<FileReader>) => void Callback, der beim Abbruch aufgerufen wird. event.target ist die betroffene FileReader-Instanz, event.loaded gibt die bis dahin gelesenen Bytes an.
$options boolean | AddEventListenerOptions false Optionale Listener-Optionen wie once oder signal.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Der Handler erhält ein ProgressEvent.

Beispiele

Lesevorgang per Button abbrechen (addEventListener)

const input = document.querySelector('#datei');
const cancelBtn = document.querySelector('#abbrechen');
const status = document.querySelector('#status');

let reader = null;

input.addEventListener('change', () => {
  const file = input.files[0];
  if (!file) return;

  reader = new FileReader();

  reader.addEventListener('abort', (event) => {
    status.textContent = `Abgebrochen nach ${event.loaded} von ${event.total} Bytes`;
    console.log('readyState:', reader.readyState, 'result:', reader.result);
  });

  reader.addEventListener('load', () => {
    status.textContent = `Fertig: ${reader.result.byteLength} Bytes gelesen`;
  });

  reader.readAsArrayBuffer(file);
});

cancelBtn.addEventListener('click', () => {
  // abort() hat nur bei readyState LOADING (1) eine Wirkung
  if (reader?.readyState === FileReader.LOADING) {
    reader.abort();
  }
});
readyState: 2 result: null

Handler über die onabort-Eigenschaft setzen und wieder entfernen

const blob = new Blob(['x'.repeat(10_000_000)], { type: 'text/plain' });
const reader = new FileReader();

reader.onabort = () => console.log('abort ausgelöst');
reader.onloadend = () => console.log('loadend ausgelöst');

reader.readAsText(blob);
reader.abort(); // sofort abbrechen

// Handler später wieder entfernen
reader.onabort = null;
abort ausgelöst loadend ausgelöst

Abbruch in einem Promise-Wrapper behandeln

const readFileAsText = (file, signal) =>
  new Promise((resolve, reject) => {
    const reader = new FileReader();

    const onAbort = () => reader.abort();
    signal?.addEventListener('abort', onAbort, { once: true });

    reader.addEventListener('load', () => resolve(reader.result));
    reader.addEventListener('error', () => reject(reader.error));
    reader.addEventListener('abort', () =>
      reject(new DOMException('Lesen abgebrochen', 'AbortError'))
    );
    reader.addEventListener('loadend', () =>
      signal?.removeEventListener('abort', onAbort)
    );

    reader.readAsText(file);
  });

const controller = new AbortController();
const file = new File(['Hallo Welt'], 'gruss.txt');

const promise = readFileAsText(file, controller.signal);
controller.abort();

try {
  await promise;
} catch (err) {
  console.log(err.name, '-', err.message);
}
AbortError - Lesen abgebrochen

// Wichtig · Fallstricke

  • Nur bei laufendem Lesevorgang: Ruft man abort() auf, während readyState EMPTY (0) oder DONE (2) ist, passiert nichts. Es wird dann auch kein abort-Ereignis ausgelöst.
  • Kein Ergebnis: Nach dem Abbruch ist reader.result null. Teildaten bekommst du nicht.
  • Ereignisreihenfolge: Auf abort folgt immer loadend, load und error werden dagegen nicht ausgelöst. Wer nur auf load und error hört, verpasst Abbrüche. Bei Promise-Wrappern bleibt das Promise dann für immer offen.
  • Neuer Lesevorgang im Handler: Ein neues readAs…() direkt im abort-Handler zu starten, ist erlaubt. Die Spezifikation hat dazu aber Sonderfälle, zum Beispiel wird das folgende loadend unterdrückt. Übersichtlicher ist es, für jeden Lesevorgang eine neue FileReader-Instanz zu verwenden.
  • Kompatibilität: Das Ereignis und onabort werden von allen modernen Browsern unterstützt, auch in Web Workern. In Workern gibt es zusätzlich FileReaderSync, das kein abort-Ereignis kennt. Für moderne Anwendungen sind Blob.prototype.text() und Blob.prototype.arrayBuffer() oft einfacher. Sie lassen sich allerdings nicht abbrechen.