为什么对IDBObjectStore.get()的这种调用会导致令人困惑的行为?

时间:2015-01-18 00:58:07

标签: javascript debugging asynchronous google-chrome-extension indexeddb

我正试图使用​​indexedDB来存储数据客户端。

考虑以下代码:

function queryURL(message, sender)
{
    chrome.contextMenus.removeAll();

    var openRequest = indexedDB.open("Tags",1);
    openRequest.onsuccess = function(event){
        var queryURL = message['host'];
        var db = event.target.result;
        var objectStore = db.transaction("domains").objectStore("domains");
        var query = objectStore.get(queryURL);

        query.onsuccess = function(event){                                                                                                                                                                                                                     
            alert(query.result);
            delete query.result["domain"];
            createMenuItems(query.result);
            available_commands=request.result;        
        };

        db.onerror = function(event){
            console.log("an error bubbled up during a transaction.");
        };

    };
    openRequest.onerror = function(event){
        console.log("error opening DB");
    };  
}  

我不完全理解查询中应该发生什么。

无论所查询的密钥是否在数据库中,结果都是相同的: query.onsuccess()运行query.resultundefined所以{。}}    我尝试从中删除密钥时出现代码错误并退出    query.result

如果找不到query.onsuccess()应该    跑步,对吗?

如果找到query.result应该保留该对象    对应那个键,对吗?


如果有帮助,这是我用来初始化数据库的代码:

const db_name="Tags";                                                                                                                                                                                                                                          


var request = window.indexedDB.open(db_name, 1); 
var tags  = [ 
    //codes: 0 - markdown wrap tag
    //       1 - HTML wrap tag 
    //       2 - single tag
    { domain: "www.youtube.com", 

      bold:["*",0],
      strikethrough:["-",0],
      italic:["_",0] 
    },  


    { domain: "www.stackoverflow.com", 

      bold:["<strong>",1], 
      italic:["<em>",1],
      strikethrough:["<del>",1],
      superscript:["<sup>",1],
      subscript:["<sub>",1],
      heading1:["<h1>",1],
      heading2:["<h2>",1],
      heading3:["<h3>",1],
      blockquote:["<blockquote>",1],
      code:["<code>",1],
      newline:["<br>",2],
      horizontal:["<hr>",2]
    }   
];


request.onerror = function(event) {
  alert("Error opening the database");
};

request.onupgradeneeded = function(event) {
    var db = event.target.result;
    alert("I'm doing stuff!"); 
    var objectStore = db.createObjectStore("domains", {keyPath: "domain" }); 
    objectStore.createIndex("domain", "domain", { unique: true }); 

    objectStore.transaction.onComplete = function(event) {
        var domanStore=db.transaction("domains","readwrite").objectStore("domains");
        for(var i in tags)
        {
            domainStore.add(tags[i]);
        }
    }   
};

以下是我正在使用的资源的一些链接:

Using IndexedDB

IDBObjectStore

IDBRequest

2 个答案:

答案 0 :(得分:1)

查找结果为空或未定义是一个成功的查询。是的,您可以onsuccessresult === undefined进行通话。

onerror仅保留用于中断的内容,例如你提供了一个无效的密钥。

来自IDBObjectStore.get docs

  

注意:此方法会产生相同的结果:a)数据库中不存在的记录和b)具有未定义值的记录。要区分这些情况,请使用相同的密钥调用openCursor()方法。如果记录存在,该方法提供游标,如果不存在则提供游标。

答案 1 :(得分:1)

是。即使没有删除记录,delete方法返回成功也会更加令人困惑。

由于请求错误事件是可取消的冒泡事件,因此即使没有找到记录也无法调用错误回调。如果请求出错并且未阻止错误,则其中止的事务将被中止,并且也将调用indexedDB.onerror。因此,使用未定义结果调用成功仍然比调用错误更好。