2

在下面的getCursor_函数中,请解释我如何确定是否IndexedDb已打开,如果未打开则重新运行函数?getCursor_运行正确。但是,由于所有这些调用都是异步的,因此在数据库完成打开之前执行该函数会失败。

此代码在单独的进程中执行:

var ixDb;
var ixDbRequest;

ixDbRequest = window.indexedDB.open(dbName, dbVersion);

ixDbRequest.onsuccess = function (e) {
            ixDb = ixDbRequest.result || e.result;
}; 

getCursor_除非ixDbRequest尚未完成执行,否则以下功能可以正常工作。我想出了如何测试它,但我不确定如何在开放数据库请求仍在运行的实例中等待。

function getCursor_(objectStoreName) {
    if (!ixDb) {
        if (ixDbRequest) {
            // "Database is still opening.  Need code to wait or re-run 
            // once completed here.
            // I tried the following with no luck:
            ixDbRequest.addEventListener ("success",
                getCursor_(objectStoreName), false); 
            return;
        }
    }

    var transaction = ixDb.transaction(objectStoreName, 
                                       IDBTransaction.READ_ONLY);
    var objectStore = transaction.objectStore(objectStoreName);  
    try{
        var request = objectStore.openCursor(); 
        return request;
    }
    catch(e){
        console.log('IndexedDB Error' + '(' + e.code + '): ' + e.message);
    }
}

更新如下:

@Dangerz 的回答绝对帮助我走上了正轨。然而,由于函数调用是异步的,我最终还不得不添加一个回调,以便在“成功”事件最终触发后真正能够使用游标,并且我能够获得请求的 IndexedDb 游标。最终的工作函数如下(稍微重构以删除 "if(!ixDb)" 上面的负面逻辑。如果有人看到改进的余地,我完全愿意接受建议!

//****************************************************************************
//Function getCursor - Returns a cursor for the requested ObjectStore
//  objectStoreName  - Name of the Object Store / Table "MyOsName" 
//         callback  - Name of the function to call and pass the cursor 
//                     request back to upon completion.
//                     Ex. getCursor_("ObjectStore_Name", MyCallBackFunction);
//                     Function MyCallBackFunction(CursorRequestObj) { 
//                     CursorRequestObj.onsuccess = 
//                               function() {//do stuff here};
//                     }
//****************************************************************************
function getCursor_(objectStoreName, callback) {
  //The the openCursor call is asynchronous, so we must check to ensure a 
  // database connection has been established and then provide the cursor 
  // via callback. 
  if (ixDb) {
      var transaction = 
        ixDb.transaction(objectStoreName, IDBTransaction.READ_ONLY);
      var objectStore = transaction.objectStore(objectStoreName); 

      try{
        var request = objectStore.openCursor(); 
        callback(request);
        console.log('ixDbEz: Getting cursor request for ' 
                    + objectStoreName + ".");
      }
      catch(e){
        console.log('ixDbEz Error' + ' getCursor:(' 
                    + e.code + '): ' + e.message);
      } 
  }
  else { 
    if (ixDbRequest) {
      ixDbRequest.addEventListener ("success"
                    , function() { getCursor_(objectStoreName, callback); }
                    , false);
    }
  }
}
4

1 回答 1

2

将您的 addEventListener 行更改为:

ixDbRequest.addEventListener ("success", function() { getCursor_(objectStoreName) }, false);
于 2012-07-25T07:24:43.537 回答