Electron中neDB仅完全重启加载,Windows下重载失效问题求助
解决Electron重载时neDB .find()不执行的问题
这个问题我之前跨平台开发Electron应用时也碰到过,核心原因主要有两个:每次调用LoadRaces都重复创建数据库实例,以及没有等待loadDatabase异步操作完成就执行查询,再加上Windows和Mac的文件系统锁定机制差异,最终导致重载时数据库加载失败。
问题分析
- 重复实例导致文件锁冲突:你现在每次调用
LoadRaces都会重新require("nedb")并新建Datastore实例,重载应用时旧实例可能还持有数据库文件的锁——Windows下文件锁机制比Mac更严格,新实例无法正常读取文件。 - 异步操作未等待:
races.loadDatabase()是异步方法,但你直接同步调用了races.find()。首次启动时数据库加载速度快,刚好能赶上查询执行;但重载时受文件状态或Electron缓存影响,加载速度变慢,查询执行时数据库还没准备好,导致回调永远不触发。
解决方案
1. 改用全局单例数据库实例
把数据库实例抽成单独模块,确保整个应用生命周期内只有一个实例,避免重复创建带来的冲突:
创建compendiumDB.js(或.ts):
const Datastore = require("nedb"); // 全局单例实例,确保整个应用只初始化一次 const racesDB = new Datastore({ filename: "Compendium.db" }); // 用Promise封装数据库加载,方便异步等待 const loadDatabase = () => { return new Promise((resolve, reject) => { racesDB.loadDatabase((err) => { if (err) { console.error("数据库加载失败:", err); reject(err); } else { resolve(); } }); }); }; module.exports = { racesDB, loadDatabase };
2. 修改LoadRaces函数,等待数据库加载完成
确保查询操作只在数据库完全加载后执行:
import { racesDB, loadDatabase } from './compendiumDB'; export async function LoadRaces(callback: (races: Race[]) => void) { try { // 等待数据库加载完成再执行查询 await loadDatabase(); console.log("Preloading Races Test"); racesDB.find({ size: { $exists: true } }, (err, docs) => { if (err) { console.error("查询种族数据失败:", err); return; } console.log("Loading Races"); // 直接传递查询结果,无需手动push数组 callback(docs); }); } catch (err) { console.error("数据库初始化失败:", err); } }
3. 调整useEffect处理异步逻辑
因为LoadRaces现在是异步函数,需要在useEffect里用异步函数包裹执行:
React.useEffect(() => { const fetchRaces = async () => { await LoadRaces((result) => { DisplayRaces(result); }); }; fetchRaces(); }, [])
额外注意事项
- 检查Windows下
Compendium.db文件的读写权限,确保Electron应用有权限访问该文件; - 如果使用相对路径存储数据库,建议用
__dirname拼接成绝对路径,避免Electron重载时工作目录变化导致的路径错误。
内容的提问来源于stack exchange,提问作者Galina Vitvitskaya
相关产品推荐
相关产品推荐

