目前,我正在为我的公司设计 IndexedDB 功能。我已经建立了一个扎实的课程,并且我所有的单元测试都有效。但是,当我尝试为客户端打开新数据库时,Reducer 的状态永远不会更新,因此站点挂起。我相信这是因为
initDatabase
方法正在寻找 Promise
的解决方案。这是我构建的减速器:
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import { DatabaseManager } from '../DatabaseManager';
// Async thunk to initialize the database
export const initializeDatabase = createAsyncThunk(
'database/initialize',
async (dbName, thunkAPI) => {
try {
const databaseManager = new DatabaseManager();
await databaseManager.initDatabase(dbName);
return databaseManager;
} catch (error) {
return thunkAPI.rejectWithValue(error.message);
}
}
);
const databaseSlice = createSlice({
name: 'database',
initialState: {
instance: null,
status: 'idle',
error: null,
},
reducers: {},
extraReducers: (builder) => {
builder
.addCase(initializeDatabase.pending, (state) => {
state.status = 'loading';
})
.addCase(initializeDatabase.fulfilled, (state, action) => {
state.status = 'succeeded';
state.instance = action.payload;
})
.addCase(initializeDatabase.rejected, (state, action) => {
state.status = 'failed';
state.error = action.error.message;
});
},
});
export default databaseSlice.reducer;
这是 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.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);
};
});
}
我需要更改什么才能解决
Promise
并将 action.payload
变为 state
?
您的代码似乎无法处理打开请求中的
upgradeneeded
事件,该事件将在首次创建数据库或版本增加时在 success
之前触发。
尝试添加一个
onupgradeneeded
处理程序,无论如何这是必要的,因为这是您创建对象存储和索引来实际保存数据的地方。