如何将IndexedDB表数据检索到变量?

时间:2014-10-01 11:25:32

标签: javascript jquery arrays asynchronous indexeddb

我在IndexedDB表中有一些非常简单地包含这些数据的数据:

var Customers = [
   { ssn: "123-45-6666", name: "Andrew", age: 22, email: "andrew@hotmail.com" },
   { ssn: "555-66-7777", name: "Gail", age: 25, email: "gail@email.me" }
];

然后我有了这个函数从IndexedDB获取数据:

function RetrieveTableRows(Table) {
   var returnData = [];

   var db = window.indexedDB.db;
   var trans = db.transaction([Table], "readwrite");
   var store = trans.objectStore(Table);

   var keyRange = IDBKeyRange.lowerBound(0);
   var cursorRequest = store.openCursor(keyRange);

   cursorRequest.onerror = window.indexedDB.onerror;

   cursorRequest.onsuccess = function(e) {
      var result = e.target.result;
      if(!!result == false) {
         return;
      }
      returnData.push(result.value);

      result.continue();
   };    

   return returnData; 

}

我意识到它不起作用,因为onsuccess功能是异步的,但我可以解决问题。

简单地说,我希望能够写下:

var myCustomers = RetrieveTableRows('customers');

然后能够使用变量myCustomers - 这可能吗?

我尝试过使用JQuery.deferred();方法,但似乎没有用,我知道我可以这样做:

    transaction.oncomplete = function() {
        ReturnTableRows(returnData);
    };                  
}
function ReturnTableRows(data) {
   //do something with the array of data
}

但我无法解决如何将其传回myCustomers变量的问题。

2 个答案:

答案 0 :(得分:4)

使用延迟对象,你应该可以做这样的事情

function RetrieveTableRows(Table) {
   var returnData = [];
   //setup deferred object
   var defer = $.Deferred();
   var db = window.indexedDB.db;
   var trans = db.transaction([Table], "readwrite");
   var store = trans.objectStore(Table);

   var keyRange = IDBKeyRange.lowerBound(0);
   var cursorRequest = store.openCursor(keyRange);

   cursorRequest.onerror = window.indexedDB.onerror;

   cursorRequest.onsuccess = function(e) {
      var result = e.target.result;
      if(!!result == false) {
         //when done resolve the promise, you could also do more 
         //checking and reject the data so you can handle
         //errors
         defer.resolve(returnData);

         //Make sure we exit the function once we run out of data!
         return
      }
      returnData.push(result.value);

      result.continue();
   };    

   //return the promise
   return defer.promise(); 

}

//########### then to use this ###########

//this is now a promise
var myCustomersPromise = RetrieveTableRows('customers');
var myCustomers;

//action todo when promise is resolved/rejected
$.when(myCustomersPromise ).done(function(data){
   //do something with the data/assign it to you var here
   myCustomers= data;
}).fail(function(data){

});

虽然之前我还没有真正使用过indexedDB,所以可能会误解查询是如何知道它已经完成的(我很怀疑result.continue()再次调用onSuccess,结果是错误的,当它经历了所有数据)但这是我在我的应用程序中异步执行任何操作时使用的设置

答案 1 :(得分:0)

我发现使用更少代码的替代方法更简单,并且不需要JQuery。

设定:

// Create the function(s) to grab and store the data
var myCustomers;

var getData = {
   customers: function(data) {
      myCustomers = data
   }
}

呼叫:

//Send the callback function we want into the retrieve function
trans.oncomplete = function (e) {
   RetrieveTableRows('Customers', getData.customers)     
};

功能:

function RetrieveTableRows(Table, Callback) {
   var returnData = [];

   var db = window.indexedDB.db;
   var trans = db.transaction([Table], "readwrite");
   var store = trans.objectStore(Table);

   var keyRange = IDBKeyRange.lowerBound(0);
   var cursorRequest = store.openCursor(keyRange);

   cursorRequest.onerror = window.indexedDB.onerror;

   cursorRequest.onsuccess = function(e) {
      var result = e.target.result;
      if(!!result == false) {
         // Send the information back to our specified function
         Callback(returnData);
         return
      }
      returnData.push(result.value);

      result.continue();
   };    

}