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

Mir*_*ron 4 javascript closures event-handling 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 }
Run Code Online (Sandbox Code Playgroud)

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

net*_*kin 5

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

或者您需要将 indexedDB 操作包装到一个承诺中,从而使列表人员异步:

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) })
Run Code Online (Sandbox Code Playgroud)

问题是,你创建了一个代表最终将完成的工作的承诺。您可以告诉 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欲了解详情


编辑

此外,如果你不喜欢 then,你可以使用 async wait 来凑合,它会解开 Promise。请注意,您只能在异步函数中使用await关键字:

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