2017-03-09 4 views
1

IndexedDBのonupgradeneeded()イベントで、オブジェクトストアの各レコードを更新しようとしています。それらを更新するために、私は、最初の非同期操作をプリフォームする必要があるが、これは、アップグレード・トランザクションがアクティブになることを引き起こし、私はsetTimeout()アップグレードイベントでIndexedDBを非同期で更新します。

で非同期操作をシミュレートしていますエラーにフォローコードで

Failed to execute 'update' on 'IDBCursor': The transaction is not active.

を取得します

let openRequest = indexedDB.open('myDb', 1); 

openRequest.onupgradeneeded = function (versionEvent) { 
    let db = versionEvent.target['result']; 
    let upgradeTransaction = versionEvent.target['transaction']; 

    if(versionEvent.oldVersion < 1) { 
     let objStore = db.createObjectStore('sample'); 
     objStore.add('one', '1'); 
     objStore.add('two', '2'); 
    } 

    if(versionEvent.oldVersion >= 1) { 
     let getCursor = upgradeTransaction.objectStore('sample').openCursor(); 

     getCursor.onsuccess = (e) => { 
      let cursor = e.target['result']; 
      if (cursor) { 
      setTimeout(() => { 
       cursor.update(cursor.value + ' updated'); 
       cursor.continue(); 
      }) 
      } 
     } 
    } 
}; 

https://plnkr.co/edit/DIIzLduZT1dwOEHAdzSf?p=preview

あなたはこのplunkerを実行する場合、それはのIndexedDBを初期化します。次に、バージョン番号を2に増やして再度実行すると、エラーが発生します。

更新イベントが非同期操作に依存している場合、アップグレードイベントでIndexedDBを更新するにはどうすればよいですか?

答えて

2

別のアプローチが必要です。次のオプションがあります。

  • スキーマをすぐに変更するが、後続のトランザクションに新しいデータを追加することを延期する。
  • アップグレードを実行する前にデータを取得してください。データの取得が遅いため、これは望ましくない可能性があります。
  • アップグレードが必要な場合のみ、条件付きでデータを取得します。

後者には2つのアプローチがあります。バージョン番号のないopen()を実行し、バージョンを確認して、必要な値よりも低い場合はフェッチ/アップグレードしてください。または、新しいバージョンを開き、アップグレードでアップグレードを中止することができます(リクエストからトランザクションを取得し、abort()を呼び出して)、データをフェッチしてアップグレードを再試行します。

+0

ありがとうございます!私はオプション3を使い、バージョン番号なしで 'open()'を呼び出すと思います。 – rob

関連する問題