IndexedDB records as asynchronous iterator

Viewed 149

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.

0 Answers
Related