IndexedDB初始化Promise阻塞致Redux状态未更新问题求解
解决方案
1. 必须处理onupgradeneeded事件
首次打开数据库或数据库版本升级时,IndexedDB会触发onupgradeneeded事件。未处理该事件会导致数据库请求一直处于pending状态,Promise永远无法resolve。修改initDatabase方法添加该事件监听:
async function initDatabase(dbName) { // Validate dbName if (!dbName || typeof dbName !== 'string' || !/^[a-zA-Z0-9]+$/.test(dbName)) { throw new Error('Invalid dbName: Must be a non-empty alphanumeric string'); } // Prevent reinitialization of db if already created if (this._db) { console.log(`Database ${this._db.name} is already initialized.`); return this._db; } // Standardize name that will populate in browser const request = window.indexedDB.open(dbName); return new Promise((resolve, reject) => { // 新增:处理数据库版本升级/首次创建事件 request.onupgradeneeded = (event) => { const db = event.target.result; // 根据业务需求创建对象仓库,示例: // if (!db.objectStoreNames.contains('yourStoreName')) { // db.createObjectStore('yourStoreName', { keyPath: 'id' }); // } }; request.onsuccess = (event) => { this._db = event.target.result; resolve(this._db); }; request.onerror = (event) => { console.error(`Failed to initialize ${dbName}: ${event.target.errorCode}`); reject(event.target.error); }; }); }
2. 规范已初始化场景的返回值(可选)
当前代码中已初始化时直接返回this._db,async函数会自动包装为Promise,但为了逻辑统一,可明确返回Promise:
if (this._db) { console.log(`Database ${this._db.name} is already initialized.`); return Promise.resolve(this._db); }
3. 确认Thunk调用逻辑
确保组件中正确dispatch thunk并处理结果:
import { useDispatch } from 'react-redux'; import { initializeDatabase } from './databaseSlice'; function DatabaseInitComponent() { const dispatch = useDispatch(); const initDb = async () => { try { // 使用unwrap()获取Promise的最终结果或抛出错误 await dispatch(initializeDatabase('yourDbName')).unwrap(); // 初始化成功后的逻辑 } catch (err) { console.error('数据库初始化失败:', err); } }; return <button onClick={initDb}>初始化数据库</button>; }
内容的提问来源于stack exchange,提问作者TJLSmith0831
相关产品推荐
相关产品推荐

