如何通过 objectstore.add() 获取添加到 IndexedDB 的对象的(自动递增)ID?

How to get the (autoincremented) id of an object added to an IndexedDB by objectstore.add()?

我正在开发 WebExtension 并使用 IndexedDB 来存储对象。当我存储一个新对象时,它不会是唯一的。因此,我使用自动递增的 id 来使其独一无二。第一次添加后,我会做一些工作,modify/update 一些属性,因此必须更新数据库中的对象。但是要更新一个对象,我需要知道它的 ID,但我目前还不知道。

这是我将对象添加到数据库的代码:

const dbName = "MyDb";
const dbVersion = 1;
const storeName = "MyStore";

function addObject(obj) {
    const request = window.indexedDB.open(dbName, dbVersion);
    request.onupgradeneeded = event => {
        const db = event.target.result;
        const objectStore = db.createObjectStore(storeName, { keyPath: 'id', autoIncrement: true });
    }
    request.onsuccess = event => {
        const db = event.target.result;
        const transaction = db.transaction(storeName, 'readwrite');
        const objectStore = transaction.objectStore(storeName);
        objectStore.add(obj);
        transaction.onerror = event => {
            console.error('Error while adding an object: ', event.target.error.message);
        };
        // How do I get/return the ID of the previously added object?
        transaction.onsuccess = event => {
            console.log(event.target.result);
        };
        transaction.oncomplete = event => {
            console.log(event.target.result);
        };
    }
}

addObject({prop1: "foo", prop2: "bar", prop3: "", prop4: ""});

类似问题的答案 - here and here - 添加成功后建议查询event.target.result,但是上面代码中的returns undefined,虽然对象已插入成功

那么,有没有办法获取刚刚添加的对象的ID?

事实证明,我听错了事件处理程序。您不必收听交易的 onsuccess/oncomplete,而是必须收听查询的 onsuccess

此外,我将所有内容都打包到一个 Promise 中,以便能够在可用时尽快获取 ID。

这是工作示例:

const dbName = "MyDb";
const dbVersion = 1;
const storeName = "MyStore";

function addObject(obj) {
    return new Promise(function(resolve) {
        const request = window.indexedDB.open(dbName, dbVersion);
        request.onupgradeneeded = event => {
            const db = event.target.result;
            const objectStore = db.createObjectStore(storeName, { keyPath: 'id', autoIncrement: true });
        };
        request.onsuccess = event => {
            const db = event.target.result;
            const transaction = db.transaction(storeName, 'readwrite');
            const objectStore = transaction.objectStore(storeName);
            const query = objectStore.add(obj);
            transaction.onerror = event => {
                console.error('Error while adding an object: ', event.target.error.message);
            };
            query.onsuccess = event => {
                return resolve(event.target.result); // OR: return resolve(query.result);
            };
        };
    });
}

let id = await addObject({prop1: "foo", prop2: "bar", prop3: "", prop4: ""});