如果我将buggy
设置为true
,则以下代码会在Chrome 35(但不是Firefox 29)中引发错误。
因为我在indexedDB中很新,所以我想问一下这是否应该有效。如果我删除了数据库并使用version=1
再次打开它,那么我的onupgradeneeded
回调是否应该被调用?
<html>
<head>
<script type="text/javascript">
var i = 1000;
var buggy = true;
function open() {
var version = buggy ? 1 : 1001 - i;
var request = indexedDB.open("test", version);
var upgraded = false;
request.onupgradeneeded = function() {
upgraded = true;
console.log("upgraded ok");
}
request.onsuccess = function() {
if (!upgraded) {
throw "Not upgraded";
}
console.log("open ok");
if (--i != 0) { obliterate(); }
}
request.onerror = function() {
throw "Error in open";
}
}
function obliterate() {
var request = indexedDB.deleteDatabase("test");
request.onsuccess = function() {
console.log("delete ok");
open();
}
request.onerror = function(event) {
throw "Error in obliterate.";
}
}
obliterate();
</script>
</head>
<body>
</body>
</html>
在Chrome中,使用buggy=true
,我得到:
delete ok test.html:29
upgraded ok test.html:12
open ok test.html:18
delete ok test.html:29
Uncaught Not upgraded
在Firefox中它可以正常工作。
作为旁注,在Chrome和Firefox中,这都非常缓慢 - 比如一次创建和删除数据库需要5-10秒。这是正常/预期的吗?我做错了吗?
答案 0 :(得分:2)
这是用户错误。
在Firefox和Chrome中,IndexedDB中的删除速度非常快。我还没有做过任何测量。但是要深思熟虑:在SyncedDB的测试套件中,我删除并在每个测试之间创建一个数据库。目前有67项测试,它们在不到一秒的时间内完成。数据库删除和创建绝对不是测试中最耗时的部分。
你偶然发现的是IndexedDB如何工作的棘手部分之一。 IndexedDB具有数据库连接的概念。与您的问题相关的部分是:
open
函数打开数据库来建立连接。连接由您通过open
获取的IDBDatabase表示。newVersion
属性设置为null
。问题是您在obliterate
请求open
事件处理程序中调用了onsuccess
函数。在这一点上,您正在尝试删除具有开放连接的数据库。这是有问题的,这就是为什么你的示例代码在Chrome中不起作用(看起来Firefox超时连接并完成删除,尽管有很大的延迟)。
修复方法是在versionchange
事件处理程序中附加onsuccess
事件的侦听器。在if (--i != 0) { obliterate(); }
行之后添加此内容:
request.result.onversionchange = function(e) {
if (e.newVersion === null) { // An attempt is made to delete the db
e.target.close(); // Manually close our connection to the db
}
};
插入此页后,您会发现Firefox和Chrome都无法快速创建和删除tests
数据库。