Signatur
Beschreibung
Die Eigenschaft request eines IDBCursor (bzw. IDBCursorWithValue) verweist auf das IDBRequest-Objekt, das beim Aufruf von openCursor() oder openKeyCursor() auf einem IDBObjectStore oder IDBIndex entstanden ist. Das ist immer dasselbe Request-Objekt, auch wenn der Cursor mit continue(), advance() oder continuePrimaryKey() weiterbewegt wird. Bei jedem Schritt wird dessen success-Ereignis erneut ausgelöst.
Nützlich ist die Eigenschaft vor allem, wenn du nur den Cursor zur Hand hast, etwa in einer Hilfsfunktion, die einen Cursor als Argument bekommt. Über cursor.request kommst du dann an das Request-Objekt und darüber an request.transaction, request.source oder request.readyState. Du kannst auch nachträglich Ereignis-Handler registrieren.
Die Eigenschaft ist schreibgeschützt. Eine Zuweisung wird im nicht strikten Modus ignoriert und löst im strikten Modus einen TypeError aus.
Rückgabewert
IDBRequest, über das der Cursor geöffnet wurde. Dessen result ist der Cursor selbst oder null, sobald das Ende erreicht ist.Beispiele
Request-Objekt aus dem Cursor auslesen
const openReq = indexedDB.open('shop', 1);
openReq.onupgradeneeded = () => {
const db = openReq.result;
const store = db.createObjectStore('produkte', { keyPath: 'id' });
store.add({ id: 1, name: 'Tastatur' });
store.add({ id: 2, name: 'Maus' });
};
openReq.onsuccess = () => {
const db = openReq.result;
const store = db.transaction('produkte', 'readonly').objectStore('produkte');
const cursorReq = store.openCursor();
cursorReq.onsuccess = () => {
const cursor = cursorReq.result;
if (!cursor) return;
// Immer dasselbe Request-Objekt
console.log(cursor.request === cursorReq);
console.log(cursor.value.name);
cursor.continue();
};
};
Hilfsfunktion: Transaktion und Quelle über den Cursor ermitteln
const beschreibeCursor = (cursor) => {
const req = cursor.request;
const storeName = req.source instanceof IDBIndex
? req.source.objectStore.name
: req.source.name;
console.log(`Store: ${storeName}, Modus: ${req.transaction.mode}, Status: ${req.readyState}`);
};
const db = await new Promise((resolve, reject) => {
const r = indexedDB.open('shop', 1);
r.onsuccess = () => resolve(r.result);
r.onerror = () => reject(r.error);
});
const req = db.transaction('produkte').objectStore('produkte').openCursor();
req.onsuccess = () => {
const cursor = req.result;
if (cursor) beschreibeCursor(cursor);
};
Cursor als asynchronen Iterator mit cursor.request
// Erwartet einen bereits geöffneten Cursor, z. B. das erste req.result
async function* iteriere(ersterCursor) {
let cursor = ersterCursor;
const req = cursor.request;
while (cursor) {
yield cursor.value;
cursor = await new Promise((resolve, reject) => {
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error);
cursor.continue();
});
}
}
const db = await new Promise((resolve) => {
const r = indexedDB.open('shop', 1);
r.onsuccess = () => resolve(r.result);
});
const store = db.transaction('produkte').objectStore('produkte');
const start = store.openCursor();
start.onsuccess = async () => {
start.onsuccess = null; // weitere Ereignisse übernimmt der Iterator
for await (const produkt of iteriere(start.result)) {
console.log(produkt.name);
}
};
// Wichtig · Fallstricke
- Kompatibilität: Die Eigenschaft kam erst spät in die Browser (Chrome/Edge 76, Firefox 77, Safari 15). In älteren Browsern ist sie
undefined. Vorher prüfen oder das ursprüngliche Request-Objekt selbst weiterreichen. - Immer dasselbe Objekt:
continue()undadvance()erzeugen kein neues Request-Objekt. Stattdessen wirdsuccessam ursprünglichen Request erneut ausgelöst. Wer dort neue Handler setzt, überschreibt also die alten. - Transaktionen laufen ab: Über
cursor.request.transactionkommst du nur an eine Transaktion, solange diese aktiv ist. Wartest du zwischen zwei Cursor-Schritten auf Operationen außerhalb von IndexedDB (z. B.fetchodersetTimeout), wird die Transaktion automatisch abgeschlossen. Ein anschließendescontinue()löst dann einenTransactionInactiveErroraus. - Die Eigenschaft ist nur lesbar und lässt sich nicht durch ein anderes Request-Objekt ersetzen.
- Im Hauptthread und in Web Workers verfügbar, nicht jedoch in Node.js ohne Polyfill (z. B.
fake-indexeddb).