简体   繁体   English

电子-IPC更改对象

[英]Electron - IPC changes the object

In my Electron project, I'm trying to make a module singleton by setting it as a global. 在我的Electron项目中,我试图通过将模块设置为全局模块来使其单例。 Since I use jquery in this module, I import it in the renderer process and then send it to the main via ipc and set it as global there. 由于我在此模块中使用jquery ,因此我将其导入到渲染器进程中,然后通过ipc将其发送到main并将其设置为global。 Here is related part of my code: 这是我的代码的相关部分:

main.js: main.js:

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

renderer.js: renderer.js:

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

console.log(favourites);

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

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

The outputs of console.log s in the renderer process are in the image below: 下图显示了console.log在渲染器过程中的输出:

渲染器输出

And the output of the main process is: 主要过程的输出为:

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

As you see, the object (module) I sent from the ipcRenderer is changed in the ipcMain, it lost its add and init functions. 如您所见,我从ipcRenderer发送的对象(模块)在ipcMain中已更改,丢失了其addinit函数。 Do you have any idea what is the reason of this behavior and how to fix it? 您是否知道这种行为的原因是什么以及如何解决?

PS: To be sure, I tested it with a simple objects that contains functions instead of require("favourites") . PS:可以肯定的是,我使用一个简单的对象进行了测试,该对象包含函数而不是require("favourites") They are also behaving in the same way. 他们也以相同的方式表现。 I did a workaround by using only the entities as global and passing them to all of the functions as arguments. 我通过仅将实体用作全局实体并将它们作为参数传递给所有函数来进行了变通。 However, it's not a good way in sense of code readability. 但是,从代码可读性的角度来看,这不是一个好方法。

You cannot use IPC like that. 您不能像这样使用IPC。 As noted in docs (eg. sendSync ) 如文档中所述(例如sendSync

Send a message to the main process synchronously via channel, you can also send arbitrary arguments. 通过通道同步向主进程发送消息,也可以发送任意参数。 Arguments will be serialized in JSON internally and hence no functions or prototype chain will be included. 参数将在内部以JSON序列化,因此不包含任何函数或原型链。

Your functions are simply not making it to main process. 您的功能根本就没有进入主流程。


For making a module singleton you should just use the singleton pattern in your module, and use require in main process and remote.require in renderer. 为了使模块成为单例,您应该只在模块中使用单例模式,并在渲染器中的主进程和remote.require中使用require Since require using cache (at least by default), the same module should be returned. 由于需要使用缓存(至少默认情况下),因此应返回相同的模块。 (more or less. A nice article on this) (或多或少。有关此的一篇不错的文章

For example if you export a class: 例如,如果导出一个类:

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

After @pergy's answer, I decided to drop IPC and use only the globals. 在@pergy回答之后,我决定删除IPC并仅使用全局变量。 So, here is the workaround I find: 因此,这是我找到的解决方法:

main process: 主要过程:

global.provider = {};

renderer process: 渲染过程:

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

other modules: 其他模块:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM