0

当我尝试升级数据库时,尽管IDBVersionChangeEvent抛出了一个事件(它被发送到我的onupgrade回调),onversionchange但永远不会被调用!这导致我有一个blocked事件。我不知道如何让它调用正确的处理程序。

使用 Chrome 27

//Account for different names of indexedDB
window.indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;

//Account for different names of transaction and key range
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;

var req = indexedDB.open( "test6", 2 );
req.onupgradeneeded = function(event)
{
    console.log( "This upgrade gets called" ); 

    //These do nothing
    event.target.onversionchange = function(event) { console.log( "request version change" ); };
    event.target.result.onversionchange = function(event) { console.log( "database version change" ); };
};

req.onsuccess = function(event)
{
    console.log( "This Success is called" ); 

    //These do nothing
    event.target.onversionchange = function(event) { console.log( "request version change" ); };
    event.target.result.onversionchange = function(event) { console.log( "database version change" ); };
};

req.onerror = function(event)
{
    console.log( "This error is not called" ); 
};

req.onblocked = function(event)
{
    console.log( "This blocked is sometimes called" ); 
};

//This also does nothing
req.onversionchange = function(event) { console.log( "request version change" ); };

我已经尝试在任何地方添加它,但它永远不会被调用!

编辑(未解决)它似乎indexedDB.deleteDatabase()调用了 onversionchange 处理程序!不知道为什么会这样,但升级不会。

4

3 回答 3

2

onversionchange事件由数据库实例调度。所以你应该这样听

req.onsuccess = function(e) {
  db = e.target.result;
  db.onversionchange = function(e) {
     db.close();
  }
}
于 2013-06-14T02:40:24.067 回答
1

当不同的请求尝试增加版本时,会在数据库中触发 versionchange 事件。因此,如果您添加到上面代码的底部

var req2 = indexedDB.open( "test6", 3 ); // <- note: "3"
req2.onblocked = function(e) { console.log("this will be called"); };
req2.onupgradeneeded = function(e) {
    console.log("this will be called once the first connection is closed");
};

应该调用您原来的 versionchange 事件处理程序,尽管我自己没有测试它。

编辑:它适用于我的 chrome 28.0.1500.45 beta:

<script>

var req = indexedDB.open( "test6", 2 );

req.onsuccess = function(event)
{
    console.log( "This Success is called" ); 

    //These do nothing
    event.target.onversionchange = function(event) { console.log( "request version change 2" ); };
    event.target.result.onversionchange = function(event) { console.log( "database version change 2" ); };
};

req.onerror = function(event)
{
    console.log( "This error is not called" ); 
};

req.onblocked = function(event)
{
    console.log( "This blocked is sometimes called" ); 
};

var req2 = indexedDB.open( "test6", 3 ); // <- note: "3"
req2.onblocked = function(e) { console.log("this blocked will be called"); };
req2.onupgradeneeded = function(e) {
    console.log("this will be called once the first connection is closed");
};

</script>

This Success is called dogs.html:7
database version change 2 dogs.html:11
this blocked will be called dogs.html:25
于 2013-06-15T21:38:57.677 回答
0

最有可能触发的事实onblocked意味着您在其他地方打开了一个数据库连接,可能在另一个选项卡中。

onversionchange事件在该其他选项卡(或可能许多选项卡)中触发。

您需要在那里监听onversionchangedb 连接对象上的事件,并在那里处理它。例如,您可以在那里关闭数据库连接,并显示一个对话框,指示用户他们应该重新加载页面以获取新的数据库版本。

做这样的事情:

  req.onsuccess = function(event)
  {
      var db = event.target.result
      db.onversionchange = function(event) { 
        document.body.innerHTML = "" // or a more subtle way to disable the page
        db.close()
        window.alert("please reload the page for the latest version")
      }
  };

我最近没有与 IndexedDB 密切合作,但我想我记得onblocked无论其他活动数据库连接是否有一个关闭数据库的 onversionchange 侦听器都会触发。我认为您将始终获得onblocked第一,并且如果/当所有连接都已关闭时,您将获得该onsuccess事件,从而使您可以使用新数据库。

执行此操作时看到onversionchange事件触发的原因indexedDB.deleteDatabase()是您在该选项卡中打开连接时尝试删除数据库。

于 2013-06-15T23:47:08.927 回答