如何从事件处理程序返回indexedDB查询结果?

时间:2017-09-20 15:31:54

标签: javascript event-handling closures indexeddb

我必须从indexedDB返回查询结果,但结果仅在onsuccess事件处理程序中可用。

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 }

函数调用的输出显示undefined,尽管控制台打印结果数组。请指导我如何使用变量作为输出。

2 个答案:

答案 0 :(得分:3)

您可以使用此项目:https://github.com/jakearchibald/idb

或者您需要将indexedDB操作包装到promise中,从而使列表成为异步:

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) })

问题是,您创建了一个承诺,代表最终将要完成的工作。您可以告诉JS最终,当承诺得到解决(成功)时,您希望then使用已传递给resolve的任何内容。有关详细信息,请参阅https://developer.mozilla.org/cs/docs/Web/JavaScript/Reference/Global_Objects/Promisehttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

修改

此外,如果你不喜欢thens,你可以使用async await,它可以解开承诺。请注意,您只能在异步函数中使用await关键字:

async function doStuff() {
  try {
    var people = await listPeople()
    // now you can work with ppl
  }
  catch (err) {
    // handle listPeople errors here
  }
}

答案 1 :(得分:-1)

indexedDB函数几乎都是异步的。在使用indexedDB之前,您应该熟悉编写异步Javascript。