为什么`onversionchange`从未在Chrome 27中调用过?

时间:2013-06-14 01:57:25

标签: html5 google-chrome google-chrome-extension indexeddb google-chrome-app

当我尝试升级数据库时,尽管抛出了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处理程序!不知道为什么会这样,但升级没有。

3 个答案:

答案 0 :(得分:2)

onversionchange事件是dispatched by database个实例。所以你应该这样听

req.onsuccess = function(e) {
  db = e.target.result;
  db.onversionchange = function(e) {
     db.close();
  }
}

答案 1 :(得分: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");
};

应该调用原始版本更改事件处理程序,但我自己没有测试它。

编辑:它适用于我在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

答案 2 :(得分:0)

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

onversionchange事件会在其他标签(或可能是多个标签)中触发。

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

做这样的事情:

  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()事件触发的原因是您在该选项卡中打开连接时尝试删除数据库。