While attempting to retrieve records from an IndexedDB store as an async iterator, not finding any existing recipe, I came up with this code which seems to work.
function itemPromise(req) {
return new Promise((resolve, reject) => {
req.onsuccess = (event) => {
let cursor = event.target.result;
resolve([cursor, itemPromise(req)]);
};
req.onerror = (event) => {
reject(event.target)
};
});
}
function iterRecords(req) {
let promise = itemPromise(req);
return {
async next() {
let [cursor, nextPromise] = await promise;
promise = nextPromise;
if (cursor) {
cursor.continue();
return Promise.resolve({done: false, value: cursor.value});
} else {
return Promise.resolve({done: true, value: null});
}
}
}
}
async function main() {
let db = await getDb('myDatabase'); // gets a promise on datbase
let trans = db.transaction(['myStore'], 'readonly');
let store = trans.objectStore('myStore');
let req = store.openCursor();
let iter = iterRecords(req);
while(true) {
let {done, value} = await iter.next();
if (done) {
break;
}
console.log(value);
}
}
As it is a bit complicated/convoluted I wonder if I am not missing something in my approach. I'd love some feedback before reinventing the wheel... or inventing a very bad wheel.
Note: my code is not using async *function or for await ... of as they are not supported yet by all browser.