2017-03-09 30 views
1

在IndexedDB的onupgradeneeded()事件中,我試圖更新對象存儲中的每條記錄。爲了更新他們,我需要先瓶坯的異步操作,但這會導致升級交易變得無效,出現錯誤在升級事件中異步更新IndexedDB

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

在後續代碼我模擬的異步操作與setTimeout()

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

你需要一種不同的方法。選項包括:

  • 立即更改模式,但推遲爲後續事務添加新數據。
  • 在嘗試執行升級之前獲取數據。由於提取數據很慢,因此可能不合需要。
  • 僅在需要升級時纔有條件地提取數據。

後者有兩種方法。您可以在沒有版本號的情況下執行open(),檢查版本,然後在低於所需值時執行讀取/升級。或者您可以在新版本中打開並在升級時需要中止升級(從請求中獲取事務並調用abort()),然後獲取數據並重新嘗試升級。

+0

謝謝!我想我選擇3並且調用'open()'沒有版本號。 – rob