问题
I have to return query result from indexedDB, but the result is only available in onsuccess
event handler.
1 function listPeople(){
...
4 var open = indexedDB.open("AccordionDatabase",1),
5 res;
6
7 open.onsuccess = function(){
8 var db = open.result;
9 var transaction = db.transaction("PeopleStore", "readwrite");
10 var store = transaction.objectStore("PeopleStore");
11 var request = store.getAll();
12 request.onsuccess = function(event){
13 res = event.target.result;
14 console.log(res);
15 };
16
17 // Close the db when the transaction is done
18 transaction.oncomplete = function() {
19 db.close();
20 };
21
22 };
23 return res;
24 }
The output of the function call shows undefined
, though console prints the result array. Please guide me how to use the variable as output.
回答1:
you can either use this project: https://github.com/jakearchibald/idb
or you need to wrap indexedDB operation into a promise and thus make the list people asynchronous:
function listPeople() {
// ...
return new Promise(function (resolve, reject) {
var open = indexedDB.open("AccordionDatabase",1),
open.onsuccess = function() {
var db = open.result;
var transaction = db.transaction("PeopleStore", "readwrite");
var store = transaction.objectStore("PeopleStore");
var request = store.getAll();
request.onsuccess = function(event){
resolve(event.target.result);
};
request.onerror = function(event) { reject(event) }
// Close the db when the transaction is done
transaction.oncomplete = function() {
db.close();
};
transaction.onerror = function(event) { reject(event) }
};
open.onerror = function(event) { reject(event) }
})
}
// usage:
function doWorkWithListedPeople(people) {
// ...
}
function handleErrorsDuringIndexedDbRequest(event) {
// ...
}
listPeople().then(doWorkWithListedPeople).catch(handleErrorsDuringIndexedDbRequest)
// or also
listPeople().then(function(people) { doWorkWithListedPeople(people) })
The thing is, you create a promise that represents work that will be eventually done. You can tell JS that eventually, when the promise has been resolved (success), you want to then
to work with anything that has been passed to resolve
. See https://developer.mozilla.org/cs/docs/Web/JavaScript/Reference/Global_Objects/Promise and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function for details
EDIT
furthermore, if you don't like thens, you can make do with async await, which unwraps promises. Just beware, you can only use await keyword from within async function:
async function doStuff() {
try {
var people = await listPeople()
// now you can work with ppl
}
catch (err) {
// handle listPeople errors here
}
}
回答2:
indexedDB functions are nearly all asynchronous. You should be familiar with writing asynchronous Javascript before using indexedDB.
来源:https://stackoverflow.com/questions/46326212/how-to-return-indexeddb-query-result-out-of-event-handler