Javascript 在升级事件中异步更新IndexedDB
在IndexedDB的Javascript 在升级事件中异步更新IndexedDB,javascript,database,asynchronous,transactions,indexeddb,Javascript,Database,Asynchronous,Transactions,Indexeddb,在IndexedDB的onupgradeneeded()事件中,我试图更新对象存储中的每条记录。为了更新它们,我需要首先执行一个异步操作,但这会导致升级事务变为非活动状态,并导致错误 未能对“IDBCursor”执行“update”:事务未激活。 在下面的代码中,我使用setTimeout() let openRequest=indexedDB.open('myDb',1); openRequest.onupgradeneeded=函数(versionEvent){ 让db=versionEve
onupgradeneeded()
事件中,我试图更新对象存储中的每条记录。为了更新它们,我需要首先执行一个异步操作,但这会导致升级事务变为非活动状态,并导致错误
未能对“IDBCursor”执行“update”:事务未激活。
在下面的代码中,我使用setTimeout()
let openRequest=indexedDB.open('myDb',1);
openRequest.onupgradeneeded=函数(versionEvent){
让db=versionEvent.target['result'];
让upgradeTransaction=versionEvent.target['transaction'];
如果(versionEvent.oldVersion<1){
让objStore=db.createObjectStore('sample');
objStore.add('one','1');
添加('two','2');
}
如果(versionEvent.oldVersion>=1){
让getCursor=upgradeTransaction.objectStore('sample').openCursor();
getCursor.onsuccess=(e)=>{
让游标=e.target['result'];
如果(光标){
设置超时(()=>{
cursor.update(cursor.value+'updated');
cursor.continue();
})
}
}
}
};
如果运行此plunker,它将初始化IndexedDB。然后,如果将版本号增加到2并再次运行,则会出现错误
如果更新依赖于异步操作,如何在升级事件中更新IndexedDB?您需要一种不同的方法。选择包括:
- 立即更改架构,但推迟为后续事务添加新数据
- 在尝试执行升级之前获取数据。由于获取数据的速度很慢,这可能是不可取的
- 仅当需要升级时才有条件地获取数据
后者有两种方法。您可以在没有版本号的情况下执行
open()
,检查版本,然后获取/升级低于所需的版本。或者,您可以在新版本中打开,并在upgradeneeded中中止升级(从请求中获取事务并在其上调用abort()
),然后获取数据并重新尝试升级。谢谢!我想我会选择选项3,然后在没有版本号的情况下调用open()
。
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();
})
}
}
}
};