在类中实现async indexedDB的干净方法

时间:2017-05-28 10:30:23

标签: javascript indexeddb

我有一个加载indexedDB的类。在类中的方法可以访问它之前,我需要预先加载indexedDB。目前,我在使用init()方法之前使用this.db方法,而没有初始化init()的其他方法。

我正在寻找一种更清洁的方式来实施我所拥有的,绝对不会干的。基本上每个方法目前都使用相同的代码模式实现。

问题点是:

  1. 要求另一种方法if (!this.db) {才能正确使用 处理indexedDB的初始化。
  2. 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); }; }); } 段稍后会重复播放。
  3. SQLiteDatabase db = this.getWritableDatabase();

1 个答案:

答案 0 :(得分:2)

indexedDB提供异步功能。 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();
  }
}