// ==UserScript== // @name indexedDB 操作封装 // @namespace https://scriptcat.org/ // @version 1.1.3 // @description 针对indexedDB的链式调用封装,支持批量操作。 // @author 仙灵天使 // @match http://*/* // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== // @grant none // ==/UserScript== class SimpleIDB { constructor(dbName = 'defaultDB', defaultTable = 'defaultTable') { this.dbName = dbName; this.storeName = defaultTable; // 初始化时使用默认表名 this.operationsQueue = []; // 存储操作队列 this.dbConnection = null; this.key = null; this.value = null; // 打开数据库连接并设置连接对象 const request = indexedDB.open(this.dbName); request.onupgradeneeded = (event) => { const db = event.target.result; if (!db.objectStoreNames.contains(this.storeName)) { db.createObjectStore(this.storeName, { keyPath: 'id' }); } }; request.onsuccess = (event) => { this.dbConnection = event.target.result; }; request.onerror = (event) => { console.error('Database error:', event.target.error); }; } // 设置表名 useTable(storeName) { if (!storeName || !storeName.trim()) { throw new Error('Store name cannot be empty or whitespace.'); } this.storeName = storeName; return this; } // 存储JS对象 set(key, object) { this.key = key; this.value = object; this.operationsQueue.push((conn, table, key, value) => { return new Promise((resolve, reject) => { const transaction = conn.transaction([table], 'readwrite'); const store = transaction.objectStore(table); const request = store.put({ id: key, ...value }); request.onsuccess = () => resolve(); request.onerror = (event) => reject(event.target.error); }); }); return this; } // 获取所有key getKeys(){ this.operationsQueue.push((conn, table, key, value) => { return new Promise((resolve, reject) => { const transaction = conn.transaction([table], 'readonly'); const store = transaction.objectStore(table); const request = store.getAllKeys(); request.onsuccess = () => resolve(request.result); request.onerror = (event) => reject(event.target.error); }); }); return this; } // 获取下一个key getNextKey(){ this.operationsQueue.push((conn, table, key, value) => { return new Promise((resolve, reject) => { const transaction = conn.transaction([table], 'readonly'); const store = transaction.objectStore(table); // 使用游标获取下一个键 const request = store.openCursor(); request.onsuccess = (event) => { const cursor = event.target.result; if (cursor) { // 找到第一个键,停止游标遍历 resolve(cursor.key); return; } reject('No key found in the object store.'); }; request.onerror = (event) => reject(event.target.error); }); }) return this; } // 读取JS对象 get(key) { this.key = key; this.operationsQueue.push((conn, table, key, value) => { return new Promise((resolve, reject) => { const transaction = conn.transaction([table], 'readonly'); const store = transaction.objectStore(table); const request = store.get(key); request.onsuccess = () => resolve(request.result); request.onerror = (event) => reject(event.target.error); }); }); return this; } // 移除某key数据 remove(key) { this.key = key this.operationsQueue.push((conn, table, key, value) => { return new Promise((resolve, reject) => { const transaction = conn.transaction([table], 'readwrite'); const store = transaction.objectStore(table); const request = store.delete(key); request.onsuccess = () => resolve(); request.onerror = (event) => reject(event.target.error); }); }); return this; } clear() { this.operationsQueue.push((conn, table, key, value) => { return new Promise((resolve, reject) => { const transaction = conn.transaction([table], 'readwrite'); const store = transaction.objectStore(table); const request = store.clear(); request.onsuccess = () => resolve(); request.onerror = (event) => reject(event.target.error); }); }); // 清空立即执行 this.execute() } // 执行所有队列中的操作 async execute() { const operationsToExecute = [...this.operationsQueue]; // 复制当前队列并清空原队列 this.operationsQueue = []; // 初始值是一个已解析的空数组Promise return await operationsToExecute.reduce(async (promiseChain, operation) => { const accumulatedResults = await promiseChain; // 等待前面所有操作的结果 const operationResult = await operation(this.dbConnection, this.storeName, this.key, this.value); // 等待当前操作的结果 return [...accumulatedResults, operationResult]; // 将当前操作的结果添加到累积结果中 }, Promise.resolve([])); // 直接返回结果数组,不需要再用扩展运算符 } }