Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 使用ipcMain和ipcRenderer解决Electron应用程序中事件混乱的设计模式_Node.js_Design Patterns_Electron - Fatal编程技术网

Node.js 使用ipcMain和ipcRenderer解决Electron应用程序中事件混乱的设计模式

Node.js 使用ipcMain和ipcRenderer解决Electron应用程序中事件混乱的设计模式,node.js,design-patterns,electron,Node.js,Design Patterns,Electron,因为Electron有两个进程,我们的javasript代码不是全局的,所以我发现自己发送和接收了很多事件(有很多不同的名称),来做一些我们通常只使用同一方法中的回调来做的事情。 如果我们需要共享一些全局变量(例如全局常量),则情况更糟 我目前的方法是尝试将Main和Renderer之间的连接作为websocket进行管理,但感觉不太好,可能是我做错了(而且我觉得我已经陷入了枯燥的原则,因为我无法使用ipc创建全局事件侦听器,我需要为每个“发送”和每个“打开”硬编码事件名称)。 我正在以MVC视

因为Electron有两个进程,我们的javasript代码不是全局的,所以我发现自己发送和接收了很多事件(有很多不同的名称),来做一些我们通常只使用同一方法中的回调来做的事情。
如果我们需要共享一些全局变量(例如全局常量),则情况更糟

我目前的方法是尝试将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
                              }
      }

}