Why does indexedDB objectStore.get call onsuccess even when the objectStore does not contain the object?

馋奶兔 提交于 2019-12-11 10:38:47

问题


One of the odd things about indexedDB is that a objectStore.get() request with a key that is not in the objectstore generates a success event with (event.target.results == undefined) (see: http://www.w3.org/TR/IndexedDB/#object-store the get function).

I need to trap this type of "success" and log it. Right now, I cannot find the KEY in the returned event. So I am doing a real hack and storing it in the transaction. Any advice?

   var deferred = new jQuery.Deferred(); // this is what gets returned
    var id = view.zoom + "-" + view.tile.column + "-" + view.tile.row;
    trans = DB.transaction(["Images"], "readonly");
    store = trans.objectStore("Images");
    req = store.get(id);
    trans._keyPathForGet = id; // hack
    req.onsuccess = function (e) {
        var blob = e.target.result;
        if (blob == undefined) {
            console.log("no blob of id: " + e.target.transaction._keyPathForGet);
            deferred.resolve(null);
        } else {
            var imgURL = URL.createObjectURL(blob);
            deferred.resolve(imgURL); // let leaflet know we're done, and give it the URL
            URL.revokeObjectURL(imgURL); // not sure if we're revoking it too soon here
        }

回答1:


That is artifact of over-reaching compact API design for combining key and key range. You can also find deleting a ramdon key also get success event even thought nothing was deleted. I am fine with returning success for key range query, but key query should return to error event.

Anyways, there are good alternative solutions for this kind of problems. The best way is using cursor. Storing the key is not a problem, you can keep under a function closure.

var getFile = function (id) {
  ...
  var req = store.openCursor(id);
  req.onsuccess = function(e) {
    var cursor = e.target.result;
    if (cursor) {
       var blob = cursor.value; 
       ...
    } else {
       var err = new Error();
       err.name = 'NotFoundError';
       err.id = id;
       deferred.reject(err);        
    }
  }
  return deferred;
}

You can also use count method to query a key is in a object store or not.



来源:https://stackoverflow.com/questions/14447030/why-does-indexeddb-objectstore-get-call-onsuccess-even-when-the-objectstore-does

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!