远程 | remote
remote
使用呈现程序进程中的主处理模块。
过程:渲染器
该remote
模块提供了一种在呈现程序进程(网页)和主进程之间执行进程间通信(IPC)的简单方法。
在电子,GUI 相关的模块(如dialog
,menu
等)仅在主要的过程可用,而不是在渲染器的过程。为了从渲染器进程中使用它们,需要将ipc
模块间进程消息发送到主进程。使用该remote
模块,您可以调用主过程对象的方法,而不必显式发送进程间消息,类似于Java的RMI。从渲染器进程创建浏览器窗口的示例:
const {BrowserWindow} = require('electron').remote
let win = new BrowserWindow{width: 800, height: 600})
win.loadURL('https://github.com')
注意:
对于反向操作(从主进程访问渲染器进程),可以使用webContents.executeJavascript。
远程对象
remote
模块返回的每个对象(包括函数)代表主进程中的一个对象(我们称之为远程对象或远程函数)。当调用远程对象的方法,调用远程函数或使用远程构造函数(函数)创建新对象时,实际上是发送同步进程间消息。
在上面的例子中,两个BrowserWindow
和win
分别为远程对象和new BrowserWindow
未创建BrowserWindow
在渲染器的过程对象。相反,它BrowserWindow
在主进程中创建了一个对象,并在渲染器进程中返回了相应的远程对象,即win
对象。
注意:
只有第一次引用远程对象时才存在的可枚举属性可通过远程访问。
注:
当通过remote
模块访问时,数组和缓冲区通过IPC复制。在渲染器进程中修改它们不会在主进程中修改它们,反之亦然。
远程对象的生命周期
Electron 确保只要渲染器进程中的远程对象处于活动状态(换句话说,未被垃圾收集),主进程中的相应对象将不会被释放。当远程对象被垃圾回收后,主进程中的相应对象将被解除引用。
如果远程对象在渲染器进程中泄漏(例如存储在地图中但从未释放),则主进程中的相应对象也将泄漏,因此应该非常小心,不要泄漏远程对象。
但是,字符串和数字等主值类型是通过复制发送的。
将回调传递给主流程
主流程中的代码可以接受来自渲染器的回调 - 例如remote
模块 - 但使用此功能时应该非常小心。
首先,为了避免死锁,异步调用传递给主进程的回调。您不应该期望主进程获得传递的回调的返回值。
例如,您不能Array.map
在主流程的调用中使用渲染器进程中的函数:
// main process mapNumbers.js
exports.withRendererCallback = (mapper) => {
return [1, 2, 3].map(mapper)
}
exports.withLocalCallback = () => {
return [1, 2, 3].map(x => x + 1)
}
// renderer process
const mapNumbers = require('electron').remote.require('./mapNumbers')
const withRendererCb = mapNumbers.withRendererCallback(x => x + 1)
const withLocalCb = mapNumbers.withLocalCallback()
console.log(withRendererCb, withLocalCb)
// [undefined, undefined, undefined], [2, 3, 4]
如您所见,渲染器回调的同步返回值与预期不符,并且与主流程中存在的相同回调的返回值不匹配。
其次,传递给主进程的回调将持续到主进程垃圾收集为止。
例如,下面的代码初看起来似乎是无辜的。它将close
事件的回调安装在远程对象上:
require('electron').remote.getCurrentWindow().on('close', () => {
// window was closed...
})
但请记住,直到您明确地卸载它之前,回调才会被主进程引用。如果您不这样做,每次重新加载窗口时都会重新安装回调函数,每次重新启动都会泄漏一个回调函数。
更糟糕的是,由于先前安装的回调的上下文已经发布,所以在发布close
事件时主流程中会出现异常。
为避免此问题,请确保清除对传递给主进程的渲染器回调的任何引用。这涉及清理事件处理程序,或者确保主进程明确地被告知参考来自正在退出的渲染器进程的回调。
访问主进程中的内置模块。
主过程中的内置模块作为获取器添加到remote
模块中,因此您可以像electron
模块一样直接使用它们。
const app = require('electron').remote.app
console.log(app)
方法
该remote
模块具有以下方法:
remote.require(module)
- moduleStringReturns any- require(module)主进程中返回的对象。通过它们的相对路径指定的模块将相对于主进程的入口点来解析..egproject /├──main│├──foo.js│└──index.js├──package.json└──渲染器└── index.js // main process:main / index.js const {app} = require('electron')app.on('ready',()=> {/ * ... * /})//一些相对module:main / foo.js module.exports ='bar'// renderer process:renderer / index.js const foo = require('electron')。remote.require('./ foo')// bar remote.getCurrentWindow()返回BrowserWindow- The此网页所属的窗口。remote.getCurrentWebContents()返回WebContents- 此网页的网页内容。remote.getGlobal(name)
name
串
返回any
- 主进程中name
(eg global[name]
)的全局变量。
属性
remote.process
process
主流程中的对象。这与remote.getGlobal('process')
缓存相同。