Signatur
Beschreibung
Die Eigenschaft result eines IDBRequest-Objekts enthält das Ergebnis einer asynchronen IndexedDB-Operation. Was genau darin steht, hängt von der ausgelösten Operation ab: get() liefert den gespeicherten Wert (oder undefined), add()/put() den Schlüssel des Datensatzes, getAll() ein Array, count() eine Zahl, openCursor() ein IDBCursorWithValue bzw. null. Bei indexedDB.open() (einem IDBOpenDBRequest) ist es die geöffnete IDBDatabase.
Zugreifen sollte man auf result nur, wenn die Anfrage abgeschlossen ist, also im success-Handler oder sobald readyState den Wert "done" hat. Solange die Anfrage noch läuft (readyState === "pending"), löst der Zugriff eine InvalidStateError-DOMException aus.
Ist die Anfrage fehlgeschlagen, ist result undefined. Den Grund liefert dann IDBRequest.error. Weil die ereignisbasierte API umständlich ist, verpackt man result in der Praxis oft in ein Promise.
Rückgabewert
Array, eine number, ein IDBCursor/null oder eine IDBDatabase. Bei einem Fehler ist es undefined.Beispiele
Datenbank öffnen und über result erhalten
const request = indexedDB.open('shop', 1);
request.onupgradeneeded = () => {
// Auch hier ist result bereits die IDBDatabase
const db = request.result;
db.createObjectStore('produkte', { keyPath: 'id' });
};
request.onsuccess = () => {
const db = request.result;
console.log('Geöffnet:', db.name, 'Version', db.version);
};
request.onerror = () => console.error(request.error);
Datensatz lesen und Schlüssel nach put() auslesen
const db = await new Promise((resolve, reject) => {
const r = indexedDB.open('shop', 1);
r.onupgradeneeded = () => r.result.createObjectStore('produkte', { keyPath: 'id' });
r.onsuccess = () => resolve(r.result);
r.onerror = () => reject(r.error);
});
const store = db.transaction('produkte', 'readwrite').objectStore('produkte');
const putReq = store.put({ id: 42, name: 'Tastatur', preis: 49.9 });
putReq.onsuccess = () => console.log('Gespeicherter Schlüssel:', putReq.result);
const getReq = store.get(42);
getReq.onsuccess = () => console.log('Gelesen:', getReq.result?.name);
Promise-Helfer und Cursor-Iteration
// Wandelt ein beliebiges IDBRequest in ein Promise um
const promisify = (req) => new Promise((resolve, reject) => {
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error);
});
const listeProdukte = (db) => new Promise((resolve, reject) => {
const namen = [];
const req = db.transaction('produkte').objectStore('produkte').openCursor();
req.onsuccess = () => {
const cursor = req.result; // IDBCursorWithValue oder null
if (cursor) {
namen.push(cursor.value.name);
cursor.continue(); // löst erneut success aus
} else {
resolve(namen);
}
};
req.onerror = () => reject(req.error);
});
const db = await promisify(indexedDB.open('shop', 1));
const anzahl = await promisify(db.transaction('produkte').objectStore('produkte').count());
console.log(anzahl, await listeProdukte(db));
// Wichtig · Fallstricke
- InvalidStateError: Solange
readyStatenoch"pending"ist, wirft der Zugriff aufresulteineDOMException. Lies den Wert deshalb nur imsuccess-Handler oder nach Abschluss der Anfrage aus. - undefined ist mehrdeutig:
get()liefertundefined, wenn es keinen Datensatz gibt. Einen Fehler erkennst du daran nicht, prüfe dafürerrorbzw. daserror-Ereignis. - Kopie statt Referenz: Gelesene Werte sind strukturierte Klone. Wenn du sie änderst, bleibt die Datenbank unverändert, bis du sie mit
put()zurückschreibst. - Transaktions-Lebensdauer: Wartest du zwischen zwei Anfragen mit
awaitauf etwas, das nichts mit IndexedDB zu tun hat (z. B.fetch), wird die Transaktion automatisch beendet. Folgeanfragen werfen dannTransactionInactiveError. - Cursor: Bei
openCursor()wird dasselbe Request-Objekt immer wieder verwendet.resultändert sich bei jedemcontinue()und ist am Endenull. - Unterstützt in allen modernen Browsern und in Web Workern. Im privaten Modus mancher Browser kann IndexedDB eingeschränkt sein.