下面是一段代码:
function open_db(dbname, dbversion, upgrade, onblocked) {
if (upgrade === undefined) {
upgrade = function basic_init(ev) {
…
};
}
if (onblocked === undefined) {
onblocked = function onblocked(ev) {
throw ev;
};
}
let req = window.indexedDB.open(dbname, dbversion);
return new Promise((resolve, reject) => {
req.onsuccess = ev => resolve(ev.target.result);
req.onerror = ev => reject(ev.target.error);
req.onupgradeneeded = ev => {
try {
return upgrade(ev);
} catch (error) {
reject(error);
ev.target.onsuccess = ev => ev.target.close(); // IS THIS LINE NECESSARY?
throw error; // IS THIS LINE UNNECESSARY?
}
};
req.onblocked = ev => {
try {
return onblocked(ev);
} catch (error) {
reject(error);
ev.target.onsuccess = ev => ev.target.close(); // IS THIS LINE NECESSARY?
throw error; // IS THIS LINE UNNECESSARY?
}
};
});
}
如果.onblocked
或.onupgradeneeded
处理程序throw
出现本机错误,是否会取消打开尝试?或者IDBOpenDBRequest
对象会忽略此类错误并继续前进,直到我手动关闭数据库(如果/在它打开后)?
简而言之:注解行代码是必要的吗?2它们是否 * 足够 * 防止一个悬空的打开句柄?
有没有比添加.onsuccess = ev => … .close()
更好的方法来 * 取消 * 打开请求?
1条答案
按热度按时间ocebsuys1#
您问对了问题(“是否有更好的方法来取消打开请求...?"),答案是:否,不是当前定义/实现的。您所能做的就是通过中止升级使打开成为无操作。
在
blocked
处理程序中引发没有指定的特殊行为;在这里做任何事情都是不必要的,因为它最终会跟随一个upgradeneeded
。在
upgradeneeded
上,在升级完成之前关闭连接将终止请求并中止升级,因此版本不会更改。有几种方法可以做到这一点:db = e.target.result; db.close();
)tx = e.target.transaction; tx.abort();
)upgradeneeded
事件处理程序中抛出来隐式中止事务。注意,在看到
upgradeneeded
之后,等待到success
(您的代码就是这样做的)意味着事务已经完成,升级已经发生。因此,在您的示例代码中,
throw
语句 * 是 * 有效的(它们将中止升级),而close
调用 * 不是 *。success
事件应该永远不会触发,在这种情况下,为success
添加关闭连接的处理程序就变得无关紧要了。