Node.js 使用ipcMain和ipcRenderer解决Electron应用程序中事件混乱的设计模式
因为Electron有两个进程,我们的javasript代码不是全局的,所以我发现自己发送和接收了很多事件(有很多不同的名称),来做一些我们通常只使用同一方法中的回调来做的事情。Node.js 使用ipcMain和ipcRenderer解决Electron应用程序中事件混乱的设计模式,node.js,design-patterns,electron,Node.js,Design Patterns,Electron,因为Electron有两个进程,我们的javasript代码不是全局的,所以我发现自己发送和接收了很多事件(有很多不同的名称),来做一些我们通常只使用同一方法中的回调来做的事情。 如果我们需要共享一些全局变量(例如全局常量),则情况更糟 我目前的方法是尝试将Main和Renderer之间的连接作为websocket进行管理,但感觉不太好,可能是我做错了(而且我觉得我已经陷入了枯燥的原则,因为我无法使用ipc创建全局事件侦听器,我需要为每个“发送”和每个“打开”硬编码事件名称)。 我正在以MVC视
如果我们需要共享一些全局变量(例如全局常量),则情况更糟 我目前的方法是尝试将Main和Renderer之间的连接作为websocket进行管理,但感觉不太好,可能是我做错了(而且我觉得我已经陷入了枯燥的原则,因为我无法使用ipc创建全局事件侦听器,我需要为每个“发送”和每个“打开”硬编码事件名称)。
我正在以MVC视图的形式管理windows(渲染器进程)。
也许我应该只使用主进程初始化主窗口,然后从窗口(渲染器)执行所有操作(数据库、外部api调用等)?(也就是说,MVC都在渲染器进程中,而在主进程中几乎什么都不做?) 什么是一个好的设计模式来解决这两个过程的事情从电子 如果我们需要共享一些全局var(例如 全局常数) 你可以使用 我需要为每个“发送”和每个 “开”) 这不完全是一种设计模式,但我的解决方案是定义“路由”功能 渲染器:
function sendMessageToMain(msg) {
var arg;
switch (msg) {
case "save-project":
arg = { event: "save-project", sender: "editor", data: editorJson };
break;
}
ipcRenderer.send('app-message', arg);
}
ipcMain.on('app-message', (event, arg) => {
switch (arg.event) {
case "save-project":
global.model.data = arg.data;
switch (arg.sender) {
case "editor":
// do something
break;
case "player":
// do something else
break;
}
break;
}
}
Main:
function sendMessageToMain(msg) {
var arg;
switch (msg) {
case "save-project":
arg = { event: "save-project", sender: "editor", data: editorJson };
break;
}
ipcRenderer.send('app-message', arg);
}
ipcMain.on('app-message', (event, arg) => {
switch (arg.event) {
case "save-project":
global.model.data = arg.data;
switch (arg.sender) {
case "editor":
// do something
break;
case "player":
// do something else
break;
}
break;
}
}
更具体的解决方案
用法
我试图做一些类似的、很好的变通方法,将事件名称作为数据的一部分发送。最好对代码进行一些解释,而不仅仅是转储代码。或者至少在代码中有足够多的注释,使其具有自解释性。
export default class ipcHelper {
private parse_sender
constructor() {
ipcMain.on('data', (event, args) => {
let route = args['route']
if (this[route]){ // same as before , it look if
//function if exist in class
// instance
this.parse_sender = (function (argsToSend) {
if (argsToSend['backToSender'])
{
event.sender.send('data' , argsToSend)
}
else return
}(this[route](args))) /*self caller function
it will call event.sender.send()
}
})
}
}
class ipc extends ipcHelper{
constructor() {
super()
}
some_function_name(args) {
// do stuffs here
return let argsToSend = {
backToSender : true, /* if you
don't want to send any data to
renderer, you should make it false */
// rest of other datas to send renderer
}
}
}