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