2017-05-28 45 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

相关问题