2017-05-28 48 views
1

我有一個類,加載indexedDB。在類中的方法可以訪問它之前,我需要預先加載indexedDB。目前,我在使用init()方法之前的任何其他方法沒有this.db初始化。乾淨的方式來實現異步indexedDB在類

我正在尋找一種更清潔的方式來實現我所擁有的,這絕對不是乾的。基本上,每種方法目前都使用下面的相同代碼模式來實現。

問題點是:

  1. 另一方法init()的要求,以便正確地處理 索引資料的intialization。
  2. if (!this.db) {段最終會在稍後重複。

export default class Persist { 
    constructor(storage) { 
    if (storage) { 
     this.storage = storage; 
    } 
    else { 
     throw new Error('A storage object must be passed to new Persist()'); 
    } 
    } 

    // needed to ensure that indexedDB is initialized before other methods can access it. 
    init() { 
    // initialize indexedDB: 
    const DBOpenRequest = this.storage.open('db', 1); 

    DBOpenRequest.onupgradeneeded =() => { 
     const db = DBOpenRequest.result; 
     db.createObjectStore('db', { keyPath: 'id', autoIncrement: true }); 
    }; 

    return new Promise((resolve, reject) => { 
     DBOpenRequest.onerror = event => { 
     reject(event); 
     }; 

     DBOpenRequest.onsuccess = event => { 
     console.log(`IndexedDB successfully opened: ${event.target.result}`); 
     resolve(event.result); 
     this.db = DBOpenRequest.result; 
     }; 
    }); 
    } 

    toStorage(session) { 
    if (!this.db) { 
     return this.init().then(() => { 
     const db = this.db; 
     const tx = db.transaction('db', 'readwrite'); 
     const store = tx.objectStore('db'); 
     const putData = store.put(session.toJS()); 

     return new Promise((resolve, reject) => { 
      putData.onsuccess =() => { 
      resolve(putData.result); 
      }; 

      putData.onerror =() => { 
      reject(putData.error); 
      }; 
     }); 
     }); 
    } 

    // basically a repeat of above 
    const db = this.db; 
    const tx = db.transaction('db', 'readwrite'); 
    const store = tx.objectStore('db'); 
    const putData = store.put(session.toJS()); 

    return new Promise((resolve, reject) => { 
     putData.onsuccess =() => { 
     resolve(putData.result); 
     }; 

     putData.onerror =() => { 
     reject(putData.error); 
     }; 
    }); 
    } 

回答

2

索引資料提供異步功能。 indexedDB.open是一個異步功能。看起來你正在嘗試以非異步方式使用indexedDB。不要將IDBDatabase變量作爲類實例的屬性存儲,只需將其作爲解析值返回並在類的外部對其進行管理。

function connect(name, version) { 
    return new Promise((resolve, reject) => { 
    const request = indexedDB.open(name, version); 
    request.onupgradeneeded = myUpgradeHandlerFunction; 
    request.onsuccess =() => resolve(request.result); 
    request.onerror =() => reject(request.error); 
    request.onblocked =() => { console.log('blocked'); }; 
    }); 
} 

function doStuffWithConn(conn, value) { 
    return new Promise((resolve, reject) => { 
    const tx = conn.transaction(...); 
    const store = tx.objectStore(...); 
    const request = store.put(value); 
    request.onsuccess =() => resolve(request.result); 
    request.onerror =() => reject(request.error); 
    }); 
} 

async function putValue(value) { 
    let conn; 
    try { 
    conn = await connect(...); 
    await doStuffWithConn(conn, value); 
    } catch(exception) { 
    console.error(exception); 
    } finally { 
    if(conn) 
     conn.close(); 
    } 
} 
+0

感謝您抽出時間寫下Josh。我從你的文章中學到了很多東西!事實上,我終於第一次使用'async/await'了:)。 – mythereal

相關問題