对我来说问题是如果事件最终能够成功
continue,那么这意味着我正在分叉,并且错误路径和
成功之路将会评估,并且可能会导致一些结果
不需要的行为。
那是对的。
或者我最初的理解是否正确,我不需要担心
取消成功时发生的事情,因为如果 onblocked 火灾
那么我可以有把握地推断 onsuccess 不会。
如有疑问,请实际尝试一下!您所需要的只是几个选项卡和本地服务器。添加日志记录到blocked
, success
, and upgradeneeded
请求的处理程序和versionchange
连接的处理程序。
作为背景,假设一个选项卡打开数据库的 v1:
var r = indexedDB.open('db', 1);
r.onupgradeneeded = function(e) {
var db = r.result;
// schema v1: has store s1
db.createObjectStore('s1');
};
r.onsuccess = function(e) {
window.db = r.result;
};
现在打开第二个选项卡并拉下想要升级的新代码:
var r = indexedDB.open('db', 2);
r.onupgradeneeded = function(e) {
// schema v1: has store s1
// schema v2: adds store s1
var db = r.result;
if (e.oldVersion < 1) {
db.createObjectStore('s1');
}
db.createObjectStore('s2');
};
r.onblocked = function(e) {
console.log('uh oh...');
};
您至少可以采取三种通用方法来应对升级受阻。
- 监视“旧”连接
versionchange
事件并立即关闭以解锁升级。
- 留意“新”连接
blocked
事件并通知用户关闭其他选项卡
- 留意“新”连接
blocked
事件并忽略升级。
既然您对#3 感兴趣,那么您将如何实现它:
var r = indexedDB.open('db', 2);
r.onupgradeneeded = function(e) {
// If we ever saw a blocked event, abort this upgrade.
if (r.was_blocked) {
r.transaction.abort();
return;
}
var db = r.result;
if (e.oldVersion < 1) {
db.createObjectStore('s1');
}
db.createObjectStore('s2');
};
r.onblocked = function(e) {
// Record that we saw a blocked event so this upgrade
// can be ignored.
r.was_blocked = true;
};
这与您最终得到的结果非常接近wasPreviouslyBlocked
尝试,但您的代码中存在一个严重错误:您没有中止升级,只是没有实际修改架构。因此,您最终将得到一个具有架构版本 2 的数据库,但没有任何与 v2 相比的更改。如果数据库再次打开,它将已经处于 v2,因此升级不会触发,并且您将错过预期的架构更改。