在这一行:
var request = store.add(obj);
我收到错误:
TransactionInactiveError:针对事务发出了请求 目前尚未激活,或已完成。
我在使用AJAX时只收到错误。如何在事务完成之前确保AJAX完成?我试图将信息从sql数据库加载到objectstore中。当我用Google搜索错误时,我会获得有关交易和异步性质的信息,但我还没有找到具有代码的具体解决方案。
我已经调查了回调,承诺和超时(这对我来说感觉像是黑客攻击),但是我无法让这个异步调用工作。任何帮助将不胜感激。
var req = indexedDB.open(DB_NAME, DB_VERSION);
req.onsuccess = function () {
db = this.result;
var tx = db.transaction('tblFields', 'readwrite');
var store = tx.objectStore('tblFields');
$.ajax({
type: "POST",
url: "Off.aspx/GetFields",
data: '{}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
var customers = response.d;
$(customers).each(function () {
var obj = { measureID: this.measureID, measureName: this.measureName, fieldName: this.fieldName };
var request = store.add(obj);
});
},
failure: function (response) {
alert(response.d);
},
error: function (response) {
alert(response.d);
}
});
}
答案 0 :(得分:1)
您的成功回调是异步执行的。将事务初始化代码移动到回调中应该可以解决问题:
success: function (response) {
var customers = response.d;
var tx = db.transaction('tblFields', 'readwrite');
var store = tx.objectStore('tblFields');
$(customers).each(function () {
var obj = { measureID: this.measureID, measureName: this.measureName, fieldName: this.fieldName };
var request = store.add(obj);
});
},
答案 1 :(得分:0)
如果indexedDB检测到某个事务没有活动请求,它会在短时间后关闭。当您发出ajax请求时,不会立即得到响应。在您发出ajax请求和获取响应之间,idb看不到使用该事务的活动idb请求,因此它会关闭事务。
解决方案很简单。首先执行ajax请求,然后执行idb事务。这是一些伪代码:
$.ajax({
success: function(response) {
var req = indexedDB.open(...);
req.onsuccess = function(event) {
var db = event.target.result; // or this.result, or req.result
var tx = db.transaction(...);
var store = tx.objectStore(...);
for(var customer of response.d) {
var obj = {...};
store.add(obj);
}
};
}
});
如果您想使用promises并可以访问ES6,请执行以下操作:
function dbconnect(name, version, upgrade) {
return new Promise(function(resolve, reject) {
var request = indexedDB.open(name, version);
request.onupgradeneeded = upgrade;
request.onsuccess = function(event) {
var db = event.target.result;
resolve(db);
};
request.onerror = function(event) {
var error = event.target.error;
reject(error);
};
request.onblocked = function(event) {
console.warn('blocked, not fulfilling promise until unblocked');
};
});
}
function ajaxpostrequest(url) {
return new Promise(function(resolve, reject) {
$.ajax({
type: 'post',
data: '{}',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
url: url,
success: resolve,
failure: reject,
error: reject
});
});
}
function addcustomer(db, customer) {
return new Promise(function(resolve, reject) {
var tx = db.transaction(...);
var store = tx.objectStore(...);
var obj = {measureId: customer.measureId, ...};
var request = store.add(obj);
request.onsuccess = function(event) {
resolve();
};
request.onerror = function(event) {
reject(event.target.error);
};
});
}
async function request_then_connect_then_put() {
try {
var response = await fetch(url, {method:'post'});
console.log('fetched url');
var json = await response.json();
var customers = json.d;
console.log('read json object from text of url');
var db = await dbconnect(...);
console.log('connected to database', db.name);
var addpromises = customers.map((customer) => addcustomer(db, customer));
var result = await Promise.all(addpromises);
console.log('stored all customer object things');
} catch(error) {
console.debug(error);
}
}