在升级事件中异步更新 IndexedDB
Asynchronously update IndexedDB in upgrade event
在 IndexedDB 的 onupgradeneeded()
事件中,我试图更新对象存储中的每条记录。为了更新它们,我需要先执行异步操作,但这会导致升级事务变为非活动状态,并且出现错误
Failed to execute 'update' on 'IDBCursor': The transaction is not active.
在下面的代码中,我用 setTimeout()
模拟了一个异步操作
let openRequest = indexedDB.open('myDb', 1);
openRequest.onupgradeneeded = function (versionEvent) {
let db = versionEvent.target['result'];
let upgradeTransaction = versionEvent.target['transaction'];
if(versionEvent.oldVersion < 1) {
let objStore = db.createObjectStore('sample');
objStore.add('one', '1');
objStore.add('two', '2');
}
if(versionEvent.oldVersion >= 1) {
let getCursor = upgradeTransaction.objectStore('sample').openCursor();
getCursor.onsuccess = (e) => {
let cursor = e.target['result'];
if (cursor) {
setTimeout(() => {
cursor.update(cursor.value + ' updated');
cursor.continue();
})
}
}
}
};
https://plnkr.co/edit/DIIzLduZT1dwOEHAdzSf?p=preview
如果你 运行 这个 plunker 它将初始化 IndexedDB。然后,如果您将版本号增加到 2 并再次 运行,您将收到错误消息。
如果我的更新依赖于异步操作,我如何在升级事件中更新 IndexedDB?
您需要一种不同的方法。选项包括:
- 立即更改架构,但推迟为后续事务添加新数据。
- 尝试执行升级之前获取数据。由于获取数据很慢,这可能是不可取的。
- 有条件地获取数据,仅当需要升级时。
后者有两种方法。你可以做一个没有版本号的open()
,检查版本,然后fetch/upgrade如果它低于预期。或者您可以打开新版本并在 upgradeneeded 中止升级(从请求中获取事务并对其调用 abort()
)然后获取数据并重新尝试升级。
在 IndexedDB 的 onupgradeneeded()
事件中,我试图更新对象存储中的每条记录。为了更新它们,我需要先执行异步操作,但这会导致升级事务变为非活动状态,并且出现错误
Failed to execute 'update' on 'IDBCursor': The transaction is not active.
在下面的代码中,我用 setTimeout()
let openRequest = indexedDB.open('myDb', 1);
openRequest.onupgradeneeded = function (versionEvent) {
let db = versionEvent.target['result'];
let upgradeTransaction = versionEvent.target['transaction'];
if(versionEvent.oldVersion < 1) {
let objStore = db.createObjectStore('sample');
objStore.add('one', '1');
objStore.add('two', '2');
}
if(versionEvent.oldVersion >= 1) {
let getCursor = upgradeTransaction.objectStore('sample').openCursor();
getCursor.onsuccess = (e) => {
let cursor = e.target['result'];
if (cursor) {
setTimeout(() => {
cursor.update(cursor.value + ' updated');
cursor.continue();
})
}
}
}
};
https://plnkr.co/edit/DIIzLduZT1dwOEHAdzSf?p=preview
如果你 运行 这个 plunker 它将初始化 IndexedDB。然后,如果您将版本号增加到 2 并再次 运行,您将收到错误消息。
如果我的更新依赖于异步操作,我如何在升级事件中更新 IndexedDB?
您需要一种不同的方法。选项包括:
- 立即更改架构,但推迟为后续事务添加新数据。
- 尝试执行升级之前获取数据。由于获取数据很慢,这可能是不可取的。
- 有条件地获取数据,仅当需要升级时。
后者有两种方法。你可以做一个没有版本号的open()
,检查版本,然后fetch/upgrade如果它低于预期。或者您可以打开新版本并在 upgradeneeded 中止升级(从请求中获取事务并对其调用 abort()
)然后获取数据并重新尝试升级。