如何从事件处理程序中 return indexedDB 查询结果?

How to return indexedDB query result out of event handler?

我必须 return 从 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,但控制台会打印结果数组。请指导我如何使用变量作为输出。

indexedDB 函数几乎都是异步的。在使用 indexedDB.

之前,你应该熟悉写异步 Javascript

您可以使用这个项目: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/Promise and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function


编辑

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

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