IndexedDB - Promise 封装
IndexedDB:使用 Promise 封装进行现代异步操作
Section titled “IndexedDB:使用 Promise 封装进行现代异步操作”原生的 IndexedDB API 功能强大,但由于其基于事件的异步模型,以冗长和复杂而闻名。在现代 JavaScript 中,Promise(承诺),特别是结合 async/await 语法,提供了一种更清晰、更直观的方式来处理异步操作,而不会阻塞主线程。
我们不再需要为每个请求附加 onsuccess 和 onerror 事件处理程序,而是可以使用基于 Promise 的封装。这使我们能够编写读起来像同步代码一样的异步数据库逻辑,显著提高了可读性和可维护性。
idb 库:现代标准
Section titled “idb 库:现代标准”由 Jake Archibald 创建的 idb 库,是现代开发工作流程中用于操作 IndexedDB 的事实上的标准。它是一个轻量级、基于 Promise 的封装库,简化了原生 API,同时保留了其强大功能。它让 IndexedDB 感觉像一个现代的、对开发者友好的工具。
你可以使用 npm 等包管理器将其添加到项目中:
npm install idb然后,将其导入到你的 JavaScript 模块中:
import { openDB } from 'idb';idb 的主要增强功能
Section titled “idb 的主要增强功能”idb 库提供了一些有用的快捷方式和抽象。
简化数据库打开
Section titled “简化数据库打开”打开数据库和处理版本升级变得更加清晰。
import { openDB } from 'idb';
const db = await openDB('my-database', 1, { upgrade(db, oldVersion, newVersion, transaction) { // 这是创建和修改数据库模式的唯一地方 const store = db.createObjectStore('articles', { keyPath: 'id' }); store.createIndex('date', 'date'); },});基于 Promise 的事务和游标
Section titled “基于 Promise 的事务和游标”事务和游标在原生 API 中非常复杂,但现在它们作为 Promise 返回,使其易于与 async/await 配合使用。
// 通过键获取值const value = await db.get('articles', 'article-1');
// 添加新值await db.put('articles', { id: 'article-2', title: 'My Second Article', date: new Date() });
// 使用游标遍历存储let cursor = await db.transaction('articles').store.openCursor();
while (cursor) { console.log(cursor.key, cursor.value); cursor = await cursor.continue();}事务的 done Promise
Section titled “事务的 done Promise”idb 事务对象有一个 .done 属性,这是一个 Promise,它在事务成功完成时解决,或在失败时拒绝。这对于协调多个操作非常有用。
const tx = db.transaction('articles', 'readwrite');
// 在同一个事务中并发执行多个操作await Promise.all([ tx.store.add({ id: 'article-3', title: '...' }), tx.store.put({ id: 'article-4', title: '...' }), tx.done, // 这个 Promise 确保事务完成]);
console.log('Transaction finished!');在使用 async/await 结合 idb 时,务必将数据库操作包裹在 try...catch 块中,以处理潜在错误,例如事务失败或约束违规。
async function addArticle(article) { try { const db = await openDB('my-database', 1); await db.add('articles', article); console.log('Article added successfully!'); } catch (error) { console.error('Failed to add article:', error); }}