Signatur
Beschreibung
Mit IDBCursor.delete() entfernen Sie den Datensatz, auf den ein Cursor gerade zeigt, direkt aus dem zugrunde liegenden Object Store. Das ist praktisch, wenn Sie beim Durchlaufen einer Datenmenge anhand einer Bedingung selektiv löschen wollen, z. B. abgelaufene Cache-Einträge oder erledigte Aufgaben. Sie müssen dazu weder den Schlüssel kennen noch IDBObjectStore.delete() separat aufrufen.
Die Methode liefert sofort ein IDBRequest-Objekt zurück. Der eigentliche Löschvorgang läuft asynchron. Ist er erfolgreich, wird das success-Ereignis ausgelöst und request.result ist undefined. Der Cursor bleibt an seiner Position. Um zum nächsten Datensatz zu gelangen, rufen Sie wie gewohnt cursor.continue() oder cursor.advance() auf.
Voraussetzung ist eine Transaktion im Modus "readwrite". Außerdem muss der Cursor ein Wert-Cursor sein. Er muss also mit openCursor() geöffnet worden sein, nicht mit openKeyCursor(). Cursor über einen Index (IDBIndex.openCursor()) sind erlaubt: Gelöscht wird dann der referenzierte Datensatz im Object Store.
Wenn Sie viele Datensätze anhand eines Schlüsselbereichs löschen wollen, ist IDBObjectStore.delete(keyRange) meist deutlich schneller. cursor.delete() lohnt sich vor allem, wenn die Entscheidung vom Inhalt des Datensatzes abhängt.
Rückgabewert
IDBRequest, dessen success-Ereignis nach dem erfolgreichen Löschen ausgelöst wird. request.result ist dann undefined. Schlägt der Vorgang fehl, wird error ausgelöst.Beispiele
Erledigte Aufgaben beim Durchlaufen löschen
const openReq = indexedDB.open('todo-db', 1);
openReq.onupgradeneeded = () => {
const db = openReq.result;
const store = db.createObjectStore('todos', { keyPath: 'id', autoIncrement: true });
store.add({ title: 'Einkaufen', done: true });
store.add({ title: 'Steuer', done: false });
store.add({ title: 'Sport', done: true });
};
openReq.onsuccess = () => {
const db = openReq.result;
const tx = db.transaction('todos', 'readwrite');
const store = tx.objectStore('todos');
let deleted = 0;
store.openCursor().onsuccess = (event) => {
const cursor = event.target.result;
if (!cursor) return; // Ende erreicht
if (cursor.value.done) {
const delReq = cursor.delete();
delReq.onsuccess = () => {
deleted++;
console.log(`Gelöscht: ${cursor.value.title}`);
};
}
cursor.continue();
};
tx.oncomplete = () => console.log(`Fertig, ${deleted} Einträge entfernt`);
};
Abgelaufene Cache-Einträge mit Promise-Wrapper entfernen
// Hilfsfunktion: löscht alle Einträge, deren expires in der Vergangenheit liegt
const purgeExpired = (db) => new Promise((resolve, reject) => {
const tx = db.transaction('cache', 'readwrite');
const now = Date.now();
let count = 0;
tx.objectStore('cache').openCursor().onsuccess = ({ target }) => {
const cursor = target.result;
if (!cursor) return;
if (cursor.value.expires < now) {
cursor.delete();
count++;
}
cursor.continue();
};
tx.oncomplete = () => resolve(count);
tx.onerror = () => reject(tx.error);
});
// Nutzung
const db = await new Promise((res, rej) => {
const r = indexedDB.open('app-cache', 1);
r.onupgradeneeded = () => r.result.createObjectStore('cache', { keyPath: 'url' });
r.onsuccess = () => res(r.result);
r.onerror = () => rej(r.error);
});
const removed = await purgeExpired(db);
console.log(`${removed} abgelaufene Einträge gelöscht`);
Löschen über einen Index-Cursor
// Löscht alle Benutzer mit status 'inactive' über einen Index
const deleteInactive = (db) => {
const tx = db.transaction('users', 'readwrite');
const index = tx.objectStore('users').index('by_status');
index.openCursor(IDBKeyRange.only('inactive')).onsuccess = ({ target }) => {
const cursor = target.result;
if (!cursor) return;
console.log('Entferne Benutzer', cursor.primaryKey);
cursor.delete(); // löscht den Datensatz im Object Store
cursor.continue();
};
return new Promise((resolve) => { tx.oncomplete = resolve; });
};
// Wichtig · Fallstricke
ReadOnlyError: wird ausgelöst, wenn die Transaktion nur im Modus"readonly"läuft. Öffnen Sie sie mit"readwrite".InvalidStateError: wird ausgelöst, wenn der Cursor mitopenKeyCursor()erzeugt wurde (Schlüssel-Cursor), wenn er gerade iteriert (also nachcontinue(), aber vor dem nächstensuccess) oder wenn er bereits über das Ende hinaus gelaufen ist.TransactionInactiveError: Die Transaktion ist nicht mehr aktiv. Das passiert oft, wenn Sie zwischen zwei Cursor-Schritten mitawaitauf etwas anderes warten, etwa auffetch. IndexedDB schließt Transaktionen automatisch, sobald keine Anfragen mehr offen sind.- Nach
delete()gibtcursor.valueweiterhin den alten Wert zurück. Der Cursor zeigt noch auf die Position des gelöschten Datensatzes. - Für große Mengen, die sich über einen Schlüsselbereich eingrenzen lassen, ist
IDBObjectStore.delete(IDBKeyRange)effizienter als Löschen per Cursor. - Kompatibilität: Die Methode wird in allen modernen Browsern und in Web Workern unterstützt. In privaten Fenstern kann IndexedDB je nach Browser eingeschränkt sein.