Revise the docs of remote module.

This commit is contained in:
Cheng Zhao 2013-12-30 22:06:33 +08:00
parent 67ed72294b
commit 8d124c7157

View file

@ -1,12 +1,17 @@
# remote
It's common that the developers want to use modules in browsers from the
renderer, like closing current window, opening file dialogs, etc. Instead of
writing IPC code for every operation you want to do, atom-shell provides the
`remote` module to let you do RPC call just like using normal javascript
objects.
The `remote` module provides a simple way to do inter-process communication
between renderer process and browser process.
An example of creating a window in renderer:
In atom-shell, all GUI related modules are only available in the browser
process, if users want to call an browser side API in the renderer process
, they usually would have to explicitly send inter-process messages to the
browser process. But with the `remote` module, users can invoke methods of
objects living in browser process without sending inter-process messages
directly, like Java's
[RMI](http://en.wikipedia.org/wiki/Java_remote_method_invocation).
An example of creating a browser window in renderer process:
```javascript
var remote = require('remote');
@ -15,31 +20,50 @@ var win = new BrowserWindow({ width: 800, height: 600 });
win.loadUrl('https://github.com');
```
## Remote objects
Each object (including function) returned by `remote` module represents an
object in browser process (we call it remote object or remote function), when
you invoke methods of a remote object, or call a remote function, or even create
a new object with the remote constructor (function), you are actually sending
synchronous inter-process messages.
In the example above, both `BrowserWindow` and `win` were remote objects. And
`new BrowserWindow` didn't create a `BrowserWindow` object in renderer process,
instead it created a `BrowserWindow` object in browser process, and returned the
corresponding remote object in renderer process, namely the `win` object.
## Lifetime of remote objects
Every object returned by `remote` module represents an object in browser (e.g.
a remote object), so when you call methods of an object, or call a returned
function, or even create a object with the returned constructor, you are
indeed making a synchronous RPC call. And when the renderer releases the last
reference to the remote object, the browser would release the corresponding
reference too.
Atom-shell makes sure that as long as the remote object in renderer process
lives (in other words, has not been garbage collected), the corresponding object
in browser process would never be released. And when the remote object has been
garbage collected, the corresponding object in browser process would be
dereferenced.
This also means that, if the renderer keeps a reference to an object in
browser, the object would never be released. So be careful to never leak the
But it also means that, if the remote object is leaked in renderer process, like
being stored in a map but never got freed, the corresponding object in browser
process would also be leaked too. So you should be very careful not to leak
remote objects.
## Passing callbacks
Primary value types like strings and numbers, however, are sent by copy.
Many APIs in browser accepts callbacks, so the `remote` module also supports
passing callbacks when calling remote functions, and the callbacks passed
would become remote functions in the browser.
## Passing callbacks to browser
But in order to avoid possible dead locks, the callbacks passed to browser
would be called asynchronously in browser, so you should never expect the
browser to get the return value of the passed callback.
Some APIs in browser process accepts callbacks, and it would be attempting to
pass callbacks when calling a remote function. Yes `remote` module does support
doing this, but you should also be extremely careful on this.
Another thing is the lifetime of the remote callbacks in browser, it might be
very tempting to do things like following:
First, in order to avoid dead locks, the callbacks passed to browser process
would be called asynchronously, so you should not expect the browser process to
get the return value of the passed callbacks.
Second, the callbacks passed to browser process would not get released
automatically after they were called, instead they would persistent until the
browser process garbage collected them.
For example, following code seems innocent at first glance, It installed a
callback for the `close` event on a remote object:
```javascript
var remote = require('remote');
@ -48,35 +72,34 @@ remote.getCurrentWindow().on('close', function() {
});
```
Yes it will work correctly, but when you reload the window, the callback you
setup on the object in browser will not be erased, resources are leaked and
there is no magic in javascript to release a referenced object.
But the callback would be stored in the browser process persistently until you
explicitly uninstall it! So each time you reload your window, the callback would
be installed for once and previous callbacks were just leak. To make things
worse, since the context of previously installed callbacks have been released,
when `close` event was emitted exceptions would happen in browser process.
So if you really need to keep a reference of callbacks in browser, you should
write the callback in browser and send messages to renderer. And also make use
of DOM's events like `unload` and `beforeunload`, they will work perfectly.
So generally, unless you are clear what you are doing, you should always avoid
passing callbacks to browser process.
## remote.require(module)
* `module` String
Return a module in browser.
Returns the object returned by `require(module)` in the browser process.
## remote.getCurrentWindow()
Return the `BrowserWindow` object that represents current window.
`Note:` it doesn't return the `window` object which represents the global
scope, instead it returns an instance of the `BrowserWindow` class which is
created with `browser-window` module in browser.
Returns the [BrowserWindow](../browser/browser-window.md) object which
represents current window.
## remote.getGlobal(name)
* `name` String
Return the `global[name]` value in browser.
Returns the global variable of `name` (e.g. `global[name]`) in the browser
process.
## remote.process
Getter to return the `process` object in browser, this is the same with
Returns the `process` object in the browser process, this is the same with
`remote.getGlobal('process')` but gets cached.