我试图将数据从一个选项卡保存到indexeddb,并试图从另一选项卡获取数据。但是该操作在第二个选项卡中发生,仅当我关闭第一个选项卡或使用indexeddb.close()关闭第一个选项卡中的indexeddb时;
如何从其他选项卡(不关闭第一个选项卡或第一个选项卡中的indexeddb实例)中从indexeddb获取数据?
答案 0 :(得分:0)
存储在indexedDB中的数据可用于同一来源中的所有选项卡。首先要弄清楚两个标签都指向同一原点。
但是,indexedDB一次只能将对其数据的访问锁定到一个选项卡。如果您在一个选项卡中打开了与indexedDB数据库的连接,并尝试在第二个选项卡中打开与同一数据库的连接,则第二个连接将停止,因为它在中被阻塞另一个标签。
请注意,我说停滞不止。这是因为一旦具有打开的连接的选项卡关闭该连接,该连接最终将成功(未阻塞)。断开连接后,尝试打开连接的成功事件最终将触发。
可以通过在打开的连接上调用IDBDatabase.prototype.close或通过简单地关闭选项卡来关闭连接。
避免某些不良行为并最小化阻塞事件发生频率的一种方法是避免使用全局数据库连接。全局是指您在打开选项卡的时间,加载dom等时打开一段时间的数据库连接,然后在选项卡的整个生命周期中保持打开状态。不必在选项卡的整个生命周期中一次打开连接,而仅在需要时打开连接,然后再关闭它,然后每隔需要一次重新打开连接,然后再关闭它。这样,在打开选项卡的大部分时间里,连接是关闭的,而不是在大多数时间里都是打开的。
有了所有这些借口,那么您的问题的答案就是:
请注意“阻止”事件。在tab2中添加一个监听它的监听器。如果您看到此事件,那么您尝试在tab1连接仍处于打开状态时在tab2中进行连接。更改您的应用程序以应对这种情况。
这是侦听被阻止事件的简单示例:
function open(name, version, callback) {
var request = indexedDB.open(name, version);
request.onsuccess = function(event) {
var db = request.result;
callback(result, null);
};
request.onerror = function(event) {
console.log('Failed to connect');
callback(null, 'error');
};
request.onblocked = function(event) {
console.log('Failed to connect because blocked');
callback(null, 'blocked');
};
}
open('foo', 1, function onopen(db, error) {
if(error === 'error') {
console.log('cannot do stuff because of error');
} else if(error === 'blocked') {
console.log('cannot do stuff because blocked');
} else {
console.log('do stuff with db', db.name);
// do db operation here
// cleanup when done
db.close();
}
});