我在另一个关于检测阻止和解除阻塞事件的问题中被告知"阻止打开(或删除)未被取消,只是...被阻止.一旦解锁,打开(或删除)将继续."
我想知道应用程序应该如何响应被阻止的事件,如果有可能成功事件之后的路径仍然会发生,最终.
如果我希望我的应用快速响应并遇到阻止事件,我应该取消成功路径吗?通过路径,我指的是在成功打开数据库的情况下执行的一系列语句和函数调用和继续.
以前我认为被阻止的事件阻止了成功路径的继续.我已经编写了我的应用程序来处理阻塞事件,类似于错误,这意味着操作无法继续,并且应该报告错误,然后执行其他操作或返回空闲状态.
对我来说问题是,如果成功事件最终可以继续,那么这意味着我正在分叉,错误路径和成功路径都将进行评估,并可能导致一些不需要的行为.
或者我的初步理解是正确的,我不需要担心取消成功时发生的事情,因为如果onblocked触发,那么我可以安全地推断onsuccess不会.
做类似下面这样的事情真的很难看,但这是我想到的唯一一个避免问题的方法.
var r indexedDB.open(...);
var wasPreviouslyBlocked = false;
r.onsuccess = function() {
// Cancel the success if previously blocked
if(wasPreviouslyBlocked) {
return;
}
// Proceed as normal
doNextThing();
};
r.onblocked = function() {
wasPreviouslyBlocked = true;
};
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来应对这种情况?
对我来说问题是,如果成功事件最终可以继续,那么这意味着我正在分叉,错误路径和成功路径都将进行评估,并可能导致一些不需要的行为.
那是正确的.
或者我的初步理解是正确的,我不需要担心取消成功时发生的事情,因为如果onblocked触发,那么我可以安全地推断onsuccess不会.
如有疑问,请亲自尝试!您只需要几个选项卡和本地服务器.添加记录到blocked,success和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;
};
Run Code Online (Sandbox Code Playgroud)
现在打开第二个选项卡并下拉想要进行升级的新代码:
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...');
};
Run Code Online (Sandbox Code Playgroud)
您可以采取至少三种通用方法来响应阻止升级.
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;
};
Run Code Online (Sandbox Code Playgroud)
这与您在wasPreviouslyBlocked尝试中最终得到的结果非常接近,但是代码中存在严重错误:您不会中止升级,您只是不实际修改架构.因此,您最终会得到一个具有架构版本2的数据库,但不会对v2进行任何更改.如果数据库再次打开,它将已经在v2,因此升级不会触发,您将错过预期的架构更改.
| 归档时间: |
|
| 查看次数: |
549 次 |
| 最近记录: |