【问题标题】:Electron - IPC changes the objectElectron - IPC 改变对象
【发布时间】:2019-06-11 10:16:24
【问题描述】:

在我的 Electron 项目中,我试图通过将其设置为全局来制作模块单例。由于我在这个模块中使用了jquery,所以我在渲染器进程中将其导入,然后通过 ipc 将其发送到主程序并在那里将其设置为全局。这是我的代码的相关部分:

main.js:

ipcMain.on( "setGlobal", ( event, global_var) => {
  global[global_var[0]] = global_var[1];
  console.log(global_var);
  event.returnValue = 1;
} );

renderer.js:

const favourites = require("./components/favourites");

console.log(favourites);

ipcRenderer.sendSync("setGlobal", ["favourites", favourites]);

console.log(remote.getGlobal("favourites"));

console.logs 在渲染器进程中的输出如下图所示:

而主进程的输出是:

[ 'favourites', { favourites: [] } ]

如您所见,我从 ipcRenderer 发送的对象(模块)在 ipcMain 中发生了更改,它失去了 addinit 功能。您知道这种行为的原因是什么以及如何解决吗?

PS:可以肯定的是,我使用包含函数的简单对象而不是require("favourites") 对其进行了测试。他们也以同样的方式行事。我做了一个解决方法,只使用实体作为全局并将它们作为参数传递给所有函数。但是,从代码可读性的角度来看,这并不是一个好方法。

【问题讨论】:

    标签: node.js singleton electron ipc


    【解决方案1】:

    你不能那样使用 IPC。如文档中所述(例如sendSync

    通过通道向主进程同步发送消息,也可以发送任意参数。参数将在内部以 JSON 序列化,因此不会包含任何函数或原型链。

    您的函数根本没有进入主进程。


    要使模块单例,您应该在模块中使用单例模式,并在主进程中使用require,在渲染器中使用remote.require。由于需要使用缓存(至少默认情况下),因此应该返回相同的模块。 (或多或少。A nice article 在此)

    例如,如果您导出一个类:

    let _instance = null
    class MyClass {
      constructor() {
        if (_instance === null) _instance = this
        return _instance
      }
      ...
    }
    module.exports = MyClass
    

    【讨论】:

    • 感谢您提供翔实的回答!唯一的问题是我无法将我的模块导入主进程,因为它需要jQuery 并且导入它会产生错误。因此,我应该在渲染器中导入它。
    【解决方案2】:

    在@pergy 的回答之后,我决定放弃 IPC 并只使用全局变量。所以,这是我找到的解决方法:

    主进程:

    global.provider = {};
    

    渲染进程:

    const favourites = require("./components/favourites");
    remote.getGlobal("provider").favourites = favourites;
    

    其他模块:

    const favourites = remote.getGlobal("provider").favourites;
    

    【讨论】:

      猜你喜欢
      • 2016-06-01
      • 2016-01-03
      • 2019-02-13
      • 2021-05-11
      • 1970-01-01
      • 2017-07-08
      • 2021-09-13
      • 2018-09-17
      • 2021-02-14
      相关资源
      最近更新 更多