Javascript 异步索引
我想用indexeddb在异步模式下做一些事情,但失败了。你对我的问题有什么看法吗 守则:Javascript 异步索引,javascript,asynchronous,indexeddb,Javascript,Asynchronous,Indexeddb,我想用indexeddb在异步模式下做一些事情,但失败了。你对我的问题有什么看法吗 守则: function test(basekey) { window.indexedDB.deleteDatabase("base"); var lConnection = window.indexedDB.open("base", 1); lConnection.onsuccess = function (event) { var lDB = event.target
function test(basekey) {
window.indexedDB.deleteDatabase("base");
var lConnection = window.indexedDB.open("base", 1);
lConnection.onsuccess = function (event) {
var lDB = event.target.result;
var lTransactionGlobal = lDB.transaction(['person'], 'readwrite');
var lTransactionTable = lTransactionGlobal.objectStore('person');
var lRequest = lTransactionTable.add({key: basekey+1, name:"me"});
lRequest.onsuccess = function (e) {
window.setTimeout(function () {
console.log("Second wrote");
lRequest = lTransactionTable.add({key: basekey+2, name:"you"});
lRequest.onsuccess = function () {
lDB.close();
};
lRequest.onerror = function () {
console.error("Request 2 failed");
};
}, 0);
};
lRequest.onerror = function () {
console.error("Request 1 failed");
};
};
lConnection.onblocked = function () { console.log("Blocked"); };
lConnection.onerror = function () { console.log("Error"); };
lConnection.onupgradeneeded = function (pEvent) {
var db = pEvent.target.result;
var objectStore = db.createObjectStore("person", { keyPath: "key" });
};
}
调用测试(0)时,第二次“添加”时出现此错误:
未捕获的TransactionActiveError:未能对“IDBObjectStore”执行“add”:事务已完成
我尝试过Firefox和Chrome。这是索引数据库的一个设计点:当事务没有进一步的请求要处理时,它们会尝试立即提交。可以在创建后直接针对事务发出请求,也可以在处理程序中从该事务中的前一个请求发出的事件发出请求。因此,您不能在
setTimeout()
回调中发出进一步的请求,因为(1)它不是来自请求的事件处理程序,(2)在调用setTimeout()
之后,没有进一步的工作,事务将已经开始尝试提交
下面是一个简化的示例,数字表示事物的执行顺序
function myFunc(connection) {
var tx = connection.transaction('store');
// (1) transaction is "active" here, you can make requests.
var store = tx.objectStore('store');
store.get('key1').onsuccess = function() {
// (3) transaction is "active" again here.
store.get('key2').onsuccess = function() {
// (5) transaction is also "active" here.
setTimeout(function() {
// (7) transaction is "inactive" here, and the
// transaction will have attempted to commit,
// so this will fail.
store.get('key3'); // WILL THROW
}, 0);
// (6) transaction will be "inactive" when this returns.
// Since there are no more pending requests it will attempt
// to commit.
};
// (4) transaction will be "inactive" when this returns.
};
// (2) transaction will become "inactive" when control
// returns to the event loop here.
}
这演示了两种情况:事务在setTimeout()
回调中不处于活动状态,并且是在事务开始提交之后。但是您将分别看到第一种情况下的相同行为-例如,如果您有一个长时间运行的事务(大量异步请求),并尝试在setTimeout()
中执行某些操作,即使存在未完成的事务,例如,将setTimeout()
移动到(3)之后
您必须将工作分解为多个事务,或者首先执行所有非IDB异步工作。我害怕这个答案。。。好的,谢谢您的确认:(