在Chrome上删除数据库时,indexedDB不会重置版本 - 错误或用户错误? [英] indexedDB doesn't reset version when you delete a database on Chrome -- bug or user error?

查看:155
本文介绍了在Chrome上删除数据库时,indexedDB不会重置版本 - 错误或用户错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我将 buggy 设置为 true ,下面的代码会在Chrome 35中引发错误(但不是Firefox 29) 。

由于我在indexedDB中很新,所以我想问一下这是否应该起作用。如果我删除数据库,并用 version = 1 再次打开它,不应该我的 onupgradeneeded callback被调用? / p>

 < html> 
< head>
< script type =text / javascript>
var i = 1000;
var buggy = true;
函数open(){
var version = buggy? 1:1001 - 我;
var request = indexedDB.open(test,version);
var updated = false;
request.onupgradeneeded = function(){
upgraded = true;
console.log(已升级的好);

request.onsuccess = function(){
if(!upgraded){
throwNot upgraded;
}
console.log(open ok);
if(--i!= 0){obliterate(); }
}
request.onerror = function(){
throw打开时出错;



函数obliterate(){
var request = indexedDB.deleteDatabase(test);
request.onsuccess = function(){
console.log(delete ok);
open();
}
request.onerror = function(event){
throw错误消失。
}
}

obliterate();
< / script>
< / head>
< body>
< / body>
< / html>

在Chrome中, buggy = true ,我得到:

$ p $ 删除确定test.html:29
已升级确定test.html:12
打开ok test.html:18
delete ok test.html:29
Uncaught未升级



在Firefox中,它运行的很好。



请注意,在Chrome和Firefox中,运行速度都非常慢 - 比如5-10秒创建和删除数据库一次。这是正常的/预期的?我做错了什么?

解决方案

这是用户错误。

<在Firefox和Chrome中,IndexedDB中的删除都非常快。我没有做任何测量。但要把事情放在透视之下:在 SyncedDB 的测试套件中,我删除并创建了每一个测试。目前有67个测试,他们执行不到一秒钟。而且数据库的删除和创建绝对不是测试中耗时最多的部分。



你遇到的一个难题就是IndexedDB的工作原理之一。 IndexedDB具有数据库连接的概念。您的问题的相关部分是:


  • 通过打开数据库打开函数。连接由通过打开获取的IDBDatabase表示。
  • 只要数据库打开了连接,就不能删除数据库它。

  • 当尝试删除数据库时,将针对连接到数据库的所有打开的IDBDatabase对象触发versionchange事件。事件将 newVersion 属性设置为 null



问题在于你在打开的请求中调用了 obliterate code> onsuccess 事件处理程序。这一点你正在试图删除一个你打开连接的数据库。这是有问题的,这就是为什么你的示例代码不能在Chrome中工作(看起来,Firefox超时连接,并完成删除,虽然有一个巨大的延迟)。

解决方法是在 onsuccess 事件处理程序中为 versionchange 事件附加一个侦听器。在之后加上if(--i!= 0){obliterate();
$ b $ $ p $ $ c $ request.result.onversionchange = function(e){
if( e.newVersion === null){//试图删除db
e.target.close(); //手动关闭连接到db

};

插入这段代码,你会发现Firefox和Chrome都不会很快的创建和删除 tests 数据库。


The following code throws an error in Chrome 35 (but not Firefox 29) if I set buggy to true.

Since I'm pretty new in indexedDB I wanted to ask whether this ought to work or not. If I delete the database and open it again with version=1, shouldn't my onupgradeneeded callback get called?

<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>

In Chrome, with buggy=true, I get:

delete ok test.html:29
upgraded ok test.html:12
open ok test.html:18
delete ok test.html:29
Uncaught Not upgraded

In Firefox it works fine.

As a side note, in both Chrome and Firefox, this runs incredibly slowly -- like 5-10 seconds to create and delete the database a single time. Is this normal/expected? Am I doing something wrong?

解决方案

This is a user error.

Deletions in IndexedDB are very fast in both Firefox and Chrome. I haven't done any measurement. But to put things into perspective: In the test suite for SyncedDB I delete and create a database between every single test. There are currently 67 tests and they execute in less than a second. And the database deletions and creations are definitely not the most time consuming part of the tests.

What you've stumbled upon is one of the tricky parts of how IndexedDB works. IndexedDB has a notion of a database connection. The relevant parts with regards to your problem is:

  • You establish a connection by opening a database with the open function. The connection is represented by the IDBDatabase you acquire through open.
  • A database can not be deleted as long as their is open connections to it.
  • When an attempt is made to delete a database a 'versionchange' event is fired against all open IDBDatabase objects connected to the database. The event will have the newVersion property set to null.

The problem is that you call your obliterate function inside your open requests onsuccess event handler. It this point you are trying to delete a database at which you have an open connection. This is problematic and that is why your example code does not work in Chrome (it appears that Firefox times out the connection and completes the deletion, albeit with a huge delay).

The fix is to attach a listener for the versionchange event in your onsuccess event handler. Add this after the line 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
    }
};

Inserting this you will see that both Firefox and Chrome will no very rapidly create and delete the tests database.

这篇关于在Chrome上删除数据库时,indexedDB不会重置版本 - 错误或用户错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆