2

以下の関数で、開いたかどうかを判断する方法と、開いた関数を再実行しない場合のgetCursor_方法を説明してください。IndexedDbgetCursor_正しく実行されます。ただし、これらの呼び出しはすべて非同期であるため、データベースのオープンが完了する前に実行すると、関数は失敗します。

このコードは別のプロセスで実行されます。

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からの回答は、間違いなく私を正しい軌道に乗せるのに役立ちました。ただし、関数呼び出しは非同期であるため、「success」イベントが最終的に発生したときに実際にカーソルを使用できるようにするためにコールバックを追加する必要があり、要求された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 に答える