所以我对Electron还是个新手,我的目标是拥有一个完全离线的应用程序,可以有效地查询和显示加载的SQLite文件的结果(因此这里的SQL实践是有问题的)。
我能够查询我的数据库并获得预期的回报。但是,当我连续进行类似这样的调用时,第二个查询得到的结果与前一个调用相同。这是我的渲染器(React)的一部分。第一个查询通常与预期的一样,但是第二个res
与第一个查询相同。但是,有时候第二个查询得到的是预期的结果,而第一个查询得到的是相同的结果。无论哪种方式,它们最终都具有相同的res值。
有什么想法,到底发生了什么,我如何才能解决这个问题?我不相信ipcMain可以实现同步方法。
渲染器中的代码(React)
// called from ipcMain when database file is set
ipcRenderer.on('set-db', (event, arg) => {
// Get authors
queryDB("SELECT * FROM users;")
.then((res) => {
try {
var options = [];
res.forEach((e) => {
options.push({value: e.id, label: `@${e.name}`});
if (e.display_name != e.name) {
options.push({value: e.id, label: `@${e.display_name}`});
}
});
setAuthorOptions(options);
console.log("Set author options");
}
catch (exception) {}
});
// Get channels
queryDB("SELECT * FROM channels;")
.then((res) => {
try {
var options = [];
res.forEach((e) => {
if (allowedChannelTypes.includes(e.type)) {
options.push({value: e.id, label: `# ${e.name}`});
}
});
setChannelOptions(options);
console.log("Set channel options");
}
catch (exception) {}
});
});
下面是主进程中的代码
ipcMain.on('asynchronous-message', (event, sql) => {
if (db) {
db.all(sql, (error, rows) => {
event.reply('asynchronous-reply', (error && error.message) || rows);
});
}
return
});
和渲染器代码
export default function queryDB(sql) {
return new Promise((res) => {
ipcRenderer.once('asynchronous-reply', (_, arg) => {
res(arg);
});
ipcRenderer.send('asynchronous-message', sql);
})
}
1条答案
按热度按时间px9o7tmv1#
问题是您使用相同的通道名多次使用
ipcRenderer.once
。如文档中所述,此方法:为事件添加一次性
listener
函数。这个listener
只有在下一次向channel
发送消息时才会被调用,之后它将被删除。因此,如果您在前一个呼叫得到答复之前拨打新的呼叫,它们都将收到第一个被应答的呼叫的结果。
我不熟悉SQLite,但从我收集的信息来看,根据您使用的库,
db.all()
要么使用回调函数,要么是一个promise。我看到两种方法来解决这个问题:With a promise
如果使用promise方式,可以简单地使用
invoke
/handle
。例如:渲染器
主要
带回调
如果您更喜欢使用回调,则必须确保使用
ipcRenderer.once
的唯一通道名称,例如:渲染器
主要
如果您使用此方法,并且由于您并不总是向创建的通道发送回复,因此还需要确保使用ipcRenderer.removeListener或ipcRenderer. removeAllListener清理未使用的侦听器。