electron 电子- IPC更改对象

hmtdttj4  于 2022-12-16  发布在  Electron
关注(0)|答案(2)|浏览(186)

在我的Electron项目中,我试图通过将一个模块设置为全局来使其成为单例。由于我在此模块中使用了jquery,因此我在渲染器进程中导入它,然后通过ipc将其发送到main并在那里将其设置为全局。以下是我的代码的相关部分:
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.log s的输出如下图所示:

主流程的输出为:

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

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

PS:当然,我用一个包含函数而不是require("favourites")的简单对象进行了测试。它们的行为也是一样的。我做了一个变通方案,只使用实体作为全局,并将它们作为参数传递给所有函数。然而,从代码可读性的Angular 来看,这不是一个好方法。

20jt8wwn

20jt8wwn1#

你不能这样使用IPC。如文档中所述(例如sendSync
通过通道向主进程同步发送消息,也可以发送任意参数,参数在JSON内部序列化,不包含函数和原型链。
您的函数根本无法进入主进程。
要使一个模块成为singleton,你应该在你的模块中使用singleton模式,在主进程中使用require,在渲染器中使用remote.require。由于需要使用缓存(至少默认情况下是这样),所以应该返回相同的模块。(或多或少。进一步的阅读可以在here中找到)
例如,如果导出类:

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

goqiplq22#

在@pergy的回答之后,我决定放弃IPC,只使用全局变量。因此,我找到了以下变通方法:
主要流程:

global.provider = {};

渲染器进程:

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

其他模块:

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

相关问题