3. remote

原文:https://github.com/electron/electron/blob/master/docs/api/remote.md
译者:Lin

从渲染进程使用主进程模块

进程:渲染进程

remote模块提供一个在渲染进程(网页)进程和主进程之间做进程通讯(IPC)的简单方法。

Electron中,GUI相关的模块(例如dialogmenu等)只在主进程中有效,在渲染进程中无效。未了在渲染进程中使用它们,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模块返回的每个对象(包括函数)都代表着一个主进程(我们调用它来调用一个远程对象或远程函数)中的对象。当你调用一个远程对象的方法、调用一个远程函数,或者通过远程构造器(函数)创建一个新的对象时,你将发送一个同步的进程间消息。

上面的例子中,BrowserWindowwin都是远程对象,并且new BrowserWindow没有在渲染进程中创建一个BrowserWindow对象。相反,他在主进程中创建了一个BrowserWindow对象,并且将这个对应的远程对象返回到渲染线程中,即win对象。

注意:当远程对象第一次通过remote引用过来时只是当前的enumerable properties 。

注意:所有通过remote模块获取的数组和数据是通过进程间通讯复制过来的A。在渲染进程中修改它们并不会同时在主进程中修改,反过来也一样。

远程对象的生命周期

Electron确保在渲染进程中对应的这个远程对象会一直存在(换句话说,没有垃圾回收机制),对应的主进程中的对象也不会被回收。当远程模块已经被回收,主进程中对应的对象将被销毁。

如果远程对象在渲染进程中内存泄漏(例如存储在一个映射中没有被释放),对应的主进程中的对象也会造成内存泄漏,所以你需要非常小心的防止远程对象发生内存泄漏。

主要的值类型,例如stringsnumbers,都是通过拷贝的方式发送的。

回调到主线程

主进程中的代码可以接收渲染器的回调——来自于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)

  • module String类型

返回任意类型 - 主进程中通过require(module)返回的对象。

remote.getCurrentWindow()

返回值为BrowserWindow类型 - 这个页面所在的窗口。

remote.getCurrentWebContents()

返回值为WebContents - 这个网页的网络内容。

remote.getGlobal(name)

  • name String类型

返回任意类型 - 主进程中name对应的全局变量(例如global[name])。

属性

remote.process

主进程的process对象。这个方法类似于remote.getGlobal('process')但是会被缓存。

你可能感兴趣的:(3. remote)