Electron点击打开主窗口为父级的子窗口及PouchDB锁问题求助
Electron应用问题排查与解决:子窗口创建异常、PouchDB文件锁冲突
一、子窗口创建问题修复
你的代码存在两个关键问题导致子窗口无法正确以主窗口为父级创建:
parent属性位置错误:parent是BrowserWindow的顶层配置项,不属于webPreferences子属性,放在webPreferences里不会生效。createWindow函数参数冗余:调用createWindow('index.html')时传入的参数未被函数内部使用,直接固定加载index.html,可清理冗余参数避免混淆。
修正后的核心代码如下:
// main.js 修正后的子窗口创建函数 let childWindow; // 用let替代var,符合现代JS规范 function createChildWindow(fileName) { // 防护:确保主窗口已初始化 if (!parentWindow) return; childWindow = new BrowserWindow({ width: 1000, height: 1000, parent: parentWindow, // 移至顶层配置 webPreferences: { nodeIntegration: true, contextIsolation: false, enableRemoteModule: true, } }) childWindow.loadFile(fileName) } // 修正createWindow函数,移除冗余参数 function createWindow () { parentWindow = new BrowserWindow({ width: 1800, height: 1800, webPreferences: { nodeIntegration: true, contextIsolation: false, enableRemoteModule: true, preload: path.join(__dirname, 'preload.js') } }) parentWindow.loadFile('index.html') } // app ready时调用修正后的createWindow app.whenReady().then(() => { createWindow() app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) { createWindow() } }) })
修改后,点击主窗口链接即可正确创建以主窗口为父级的子窗口,同时通过if (!parentWindow)的判断避免了变量初始化顺序导致的异常。
二、PouchDB文件锁冲突解决
报错IO error: lock DB/Adb/LOCK: Resource temporarily unavailable的原因是:Electron每个渲染进程都是独立的Node.js进程,多进程同时访问同一个本地PouchDB文件会触发文件锁机制,导致冲突。
解决思路:主进程统一管理数据库
将所有数据库操作放在主进程执行,渲染进程通过IPC通道请求主进程完成操作,从根本上避免多进程直接访问数据库文件。
1. 主进程初始化数据库并提供IPC接口
在main.js中引入PouchDB,初始化唯一数据库实例,并监听渲染进程的IPC请求:
const PouchDB = require('pouchdb'); // 主进程创建唯一数据库实例 const db = new PouchDB('./DB/Adb'); // 监听渲染进程的数据库查询请求 ipcMain.handle('pouchdb-get', async (e, docId) => { try { return await db.get(docId); } catch (err) { throw err; } }); // 监听渲染进程的数据库保存请求 ipcMain.handle('pouchdb-put', async (e, doc) => { try { return await db.put(doc); } catch (err) { throw err; } }); // 可根据需求扩展更多操作:delete、query等
2. 渲染进程通过IPC调用数据库方法
在index.html或子窗口的html文件中,通过ipcRenderer.invoke调用主进程的数据库接口:
// 渲染进程代码示例(如electron.html) const { ipcRenderer } = require('electron'); // 获取指定文档 async function getDocument(docId) { try { const doc = await ipcRenderer.invoke('pouchdb-get', docId); console.log('获取文档:', doc); } catch (err) { console.error('获取失败:', err); } } // 保存文档 async function saveDocument(doc) { try { const result = await ipcRenderer.invoke('pouchdb-put', doc); console.log('保存成功:', result); } catch (err) { console.error('保存失败:', err); } }
如果不需要持久化本地数据,也可以使用PouchDB的内存模式(new PouchDB('mydb', { adapter: 'memory' })),但内存数据会在应用关闭后丢失,仅适合临时数据场景。
内容的提问来源于stack exchange,提问作者Dinesh s
相关产品推荐
相关产品推荐

