May 25, 2021 Electron
2. The lifecycle of the remote object
3. Pass callback functions to the main process
remote
module provides an easy way to communicate between the rendering process (web page) and the main process (IPC).
In Electron, GUI-related
modules
(such as
dialog
menu
etc.) exist only in the main process, not in the rendering process. I
n order to be able to use them from the rendering process, you need
ipc
module to send inter-process messages to the main process. U
sing
remote
module, you can call the method of the
main process object without explicitly sending interstational messages, similar to Java's
RMI.
Here is an example of creating a browser window from the rendering process:
const remote = require('electron').remote;
const BrowserWindow = remote.BrowserWindow;
var win = new BrowserWindow({ width: 800, height: 600 });
win.loadURL('https://github.com');
Note: Reverse operations (accessing the rendering process from the main process) can use webContents.executeJavascript .
remote
object returned by the remote module, including functions, represents an object in the main process (we call it a remote object or a remote function).
When you call a method of a remote object, perform a remote function, or create a new object using a remote constructor (function), you are actually sending a synchronized interstate message.
In the example
above,
BrowserWindow
win
objects, but
new
new BrowserWindow
not create a
BrowserWindow
process.
Instead, the
BrowserWindow
the
main process and the corresponding remote object, the win object, is returned during
win
process.
Note that only enumerable properties can be accessed through remote.
Electron ensures that remote objects exist in the rendering process (in other words, they are not garbage collected), and that the corresponding objects in the main process are not released. When a remote object is garbage collected, the corresponding object in the main process is dissociate.
If a remote object is leaked during the rendering process (that is, there is a table but never released), the corresponding object in the main process is also leaked, so you must be careful not to leak the remote object. I f the remote object is leaked in the renderer process (e.g. stored in a map but never freed), the corresponding object in the main process will also be leaked, so you should be very careful not to leak remote objects.
However, the main value types, such as strings and numbers, are copies that are passed.
The code in the main process can accept callback
remote
rendering process, the remote module, but you must be very, very careful when using this function.
Code in the main process can accept callbacks from the renderer - for instance the
remote
module - but you should be extremely careful when using this feature.
First, to avoid deadlocks, callback functions passed to the main process make asynchronous calls. T herefore, the main process cannot be expected to get the return value of the callback function that passed past. F irst, in order to avoid deadlocks, the callbacks passed to the main process are called asynchronously. You should not expect the main process to get the return value of the passed callbacks.
For example, you cannot pass a function from the rendering process to
Array.map
in the main process.
// 主进程 mapNumbers.js
exports.withRendererCallback = function(mapper) {
return [1,2,3].map(mapper);
}
exports.withLocalCallback = function() {
return exports.mapNumbers(function(x) {
return x + 1;
});
}
// 渲染进程
var mapNumbers = require("remote").require("./mapNumbers");
var withRendererCb = mapNumbers.withRendererCallback(function(x) {
return x + 1;
})
var withLocalCb = mapNumbers.withLocalCallback()
console.log(withRendererCb, withLocalCb) // [true, true, true], [2, 3, 4]
As you can see, the synchronous return value of the renderer callback function is not produced as expected, unlike the return value of the exact same callback function in the main process.
Second, functions passed to the main process continue to garbage collect them by the main process.
For example, the following code looks like no problem at first sight.
A callback function
close
bound to the close event of the remote object:
remote.getCurrentWindow().on('close', function() {
// blabla...
});
But remember that the main process will always keep a reference to this callback function unless it is explicitly unloaded. If you do not uninstall, the window is bound again each time it is reloaded, so that a callback function is leaked each time it restarts.
More seriously, since the context of the callback function
that was previously installed has been released, an
close
when the close event of the main process is triggered.
To avoid this problem, make sure that the callback functions passed to the renderer of the main process are cleaned up. You can clean up the event processor, or explicitly tell the master to cancel callback functions from an exited renderer process.
Built-in modules in the main process have been
remote
in the remote module, so they
electron
as if they were electron modules.
const app = remote.app;
remote
module has the following methods:
remote.require(module)
module
String
Returns the
object returned
require(module)
in the main process.
remote.getCurrentWindow()
Returns the
BrowserWindow
object to which the page belongs.
remote.getCurrentWebContents()
Returns the
WebContents
page
remote.getGlobal(name)
name
String
Returns a
global variable
name
in the main process,
or global
global[name]
remote.process
Returns the
process object in
process
process.
Equivalent
remote.getGlobal('process')
cached.