Start · Sprachen · JavaScript · Referenz · IDBObjectStore.clear()

IDBObjectStore.clear()

Methode

Löscht alle Datensätze eines Objekt-Stores asynchron und gibt sofort ein <code>IDBRequest</code> zurück, dessen <code>result</code> nach Erfolg <code>undefined</code> ist.

seit JavaScript Baseline: alle Browser (IndexedDB 1.0) Kategorie: webapi

Signatur

IDBObjectStore.prototype.clear()

Beschreibung

clear() entfernt alle Datensätze aus einem Objekt-Store. Außerdem werden alle Einträge in den Indizes gelöscht, die auf diesen Store verweisen. Der Store selbst und seine Struktur bleiben erhalten, also Schlüsselpfad (keyPath), autoIncrement-Einstellung und Indizes. Das ist praktisch, um z. B. einen Offline-Cache zurückzusetzen, beim Abmelden lokale Nutzerdaten zu entfernen oder einen Store vor einer vollständigen Neusynchronisation zu leeren.

Die Methode arbeitet asynchron: Sie gibt sofort ein IDBRequest zurück, und das eigentliche Löschen läuft im Hintergrund. Ist der Vorgang abgeschlossen, wird das Ereignis success ausgelöst und request.result ist undefined. Bei einem Fehler wird error ausgelöst. Endgültig gespeichert (persistiert) ist die Änderung erst, wenn die Transaktion mit complete abgeschlossen wurde.

Wichtig: clear() ist nur in einer Transaktion im Modus "readwrite" erlaubt. In einer "readonly"-Transaktion wirft die Methode sofort eine ReadOnlyError-DOMException. Wenn du nur einen Teil der Datensätze löschen willst, nimm stattdessen IDBObjectStore.delete() mit einem Schlüssel oder einem IDBKeyRange.

Rückgabewert

Typ
IDBRequest<undefined>
Beschreibung
Ein IDBRequest-Objekt. Nach dem Ereignis success ist result gleich undefined. Weitere Anfragen und Ereignisse (success, error) beziehen sich auf diesen Vorgang.

Beispiele

Objekt-Store mit Ereignis-Handlern leeren

const openReq = indexedDB.open('shop-db', 1);

openReq.onupgradeneeded = () => {
  openReq.result.createObjectStore('warenkorb', { keyPath: 'id' });
};

openReq.onsuccess = () => {
  const db = openReq.result;
  const tx = db.transaction('warenkorb', 'readwrite');
  const store = tx.objectStore('warenkorb');

  const req = store.clear();
  req.onsuccess = () => console.log('clear() erfolgreich, result:', req.result);
  req.onerror = () => console.error('Fehler:', req.error);

  tx.oncomplete = () => console.log('Warenkorb dauerhaft geleert');
};
clear() erfolgreich, result: undefined Warenkorb dauerhaft geleert

Promise-Wrapper mit async/await (z. B. beim Logout)

const promisify = (req) => new Promise((resolve, reject) => {
  req.onsuccess = () => resolve(req.result);
  req.onerror = () => reject(req.error);
});

const txDone = (tx) => new Promise((resolve, reject) => {
  tx.oncomplete = () => resolve();
  tx.onerror = () => reject(tx.error);
  tx.onabort = () => reject(tx.error ?? new DOMException('Abgebrochen', 'AbortError'));
});

const clearStores = async (db, storeNames) => {
  // Eine Transaktion über mehrere Stores: alles oder nichts
  const tx = db.transaction(storeNames, 'readwrite');
  await Promise.all(storeNames.map((name) => promisify(tx.objectStore(name).clear())));
  await txDone(tx);
  console.log(`Geleert: ${storeNames.join(', ')}`);
};

// Nutzung:
// const db = await promisify(indexedDB.open('app-db'));
// await clearStores(db, ['nachrichten', 'entwuerfe']);
Geleert: nachrichten, entwuerfe

Fallstrick: clear() in readonly-Transaktion

const openReq = indexedDB.open('shop-db', 1);

openReq.onsuccess = () => {
  const db = openReq.result;
  const store = db.transaction('warenkorb', 'readonly').objectStore('warenkorb');
  try {
    store.clear();
  } catch (err) {
    // Wird synchron geworfen, nicht über request.onerror gemeldet
    console.log(err.name);
  }
};
ReadOnlyError

Store leeren und Anzahl prüfen

const openReq = indexedDB.open('shop-db', 1);

openReq.onsuccess = () => {
  const db = openReq.result;
  const tx = db.transaction('warenkorb', 'readwrite');
  const store = tx.objectStore('warenkorb');

  store.put({ id: 1, artikel: 'Buch' });
  store.put({ id: 2, artikel: 'Stift' });
  store.clear();

  // Anfragen in derselben Transaktion laufen der Reihe nach ab
  const countReq = store.count();
  countReq.onsuccess = () => console.log('Anzahl nach clear():', countReq.result);
};
Anzahl nach clear(): 0

// Wichtig · Fallstricke

  • Synchron geworfene Ausnahmen (werden nicht über onerror gemeldet):
    • ReadOnlyError: Die Transaktion ist im Modus "readonly".
    • TransactionInactiveError: Die Transaktion ist schon beendet oder gerade nicht aktiv, zum Beispiel weil clear() erst nach einem await auf ein fremdes Promise oder in einem setTimeout aufgerufen wurde.
    • InvalidStateError: Der Objekt-Store wurde gelöscht.
  • Der autoIncrement-Zähler wird nicht zurückgesetzt. Nach clear() geht die Schlüsselvergabe mit dem nächsthöheren Wert weiter. Für einen echten Neustart musst du den Store in einem upgradeneeded-Handler mit deleteObjectStore() löschen und neu anlegen.
  • Das Ereignis success heißt noch nicht, dass die Daten dauerhaft gelöscht sind. Wird die Transaktion danach abgebrochen (abort() oder ein späterer Fehler), werden alle Änderungen zurückgenommen. Maßgeblich ist transaction.oncomplete.
  • Den Speicherplatz auf der Festplatte gibt der Browser nicht unbedingt sofort frei. Um die komplette Datenbank zu entfernen, nutze indexedDB.deleteDatabase().
  • Kompatibilität: Wird von allen modernen Browsern unterstützt, auch in Web Workern. Im privaten Modus älterer Safari- und Firefox-Versionen war IndexedDB teilweise eingeschränkt.