Skip to content

Commit

Permalink
review comments and some yarn 💩
Browse files Browse the repository at this point in the history
  • Loading branch information
nornagon committed May 29, 2019
1 parent 8f25f91 commit 2d40e8a
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 32 deletions.
8 changes: 4 additions & 4 deletions docs/api/ipc-main.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ Removes listeners of the specified `channel`.
### `ipcMain.handle(channel, listener)`

* `channel` String
* `listener` Function
* `listener` Function<Promise> | Function<any>
* `event` IpcMainEvent
* `...args` any[]

Expand All @@ -103,13 +103,13 @@ returned as a reply to the remote caller. Otherwise, the return value of the
listener will be used as the value of the reply.

```js
// main process
// Main process
ipcMain.handle('my-invokable-ipc', async (event, ...args) => {
const result = await somePromise(...args)
return result
})

// renderer process
// Renderer process
async () => {
const result = await ipcRenderer.invoke('my-invokable-ipc', arg1, arg2)
// ...
Expand All @@ -123,7 +123,7 @@ WebContents is the source of the invoke request.
### `ipcMain.handleOnce(channel, listener)`

* `channel` String
* `listener` Function
* `listener` Function<Promise> | Function<any>
* `event` IpcMainEvent
* `...args` any[]

Expand Down
19 changes: 9 additions & 10 deletions docs/api/ipc-renderer.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ Send a message to the main process asynchronously via `channel`, you can also
send arbitrary arguments. Arguments will be serialized as JSON internally and
hence no functions or prototype chain will be included.

The main process handles it by listening for `channel` with [`ipcMain`](ipc-main.md) module.
The main process handles it by listening for `channel` with the
[`ipcMain`](ipc-main.md) module.

### `ipcRenderer.invoke(channel[, arg1][, arg2][, ...])`

Expand All @@ -73,22 +74,20 @@ Send a message to the main process asynchronously via `channel` and expect an
asynchronous result. Arguments will be serialized as JSON internally and
hence no functions or prototype chain will be included.

The main process should listen for `channel` with the [`ipcMain`](ipc-main.md)
module, and send a result by calling `event.reply()`.
The main process should listen for `channel` with
[`ipcMain.handle()`](ipc-main.md#ipcmainhandlechannel-listener).

For example:
```javascript
// Renderer
// Renderer process
ipcRenderer.invoke('some-name', someArgument).then((result) => {
// ...
})

// Main
ipcMain.on('some-name', (event, someArgument) => {
doSomeWork().then(() => {
// ...
event.reply(someResult)
})
// Main process
ipcMain.handle('some-name', async (event, someArgument) => {
const result = await doSomeWork(someArgument)
return result
})
```

Expand Down
14 changes: 5 additions & 9 deletions lib/browser/api/ipc-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,22 @@ import { EventEmitter } from 'events'
import { IpcMainEvent } from 'electron'

class IpcMain extends EventEmitter {
_invokeHandlers: {[channel: string]: (e: IpcMainEvent, ...args: any[]) => void};
constructor () {
super()
this._invokeHandlers = {}
}
private _invokeHandlers: Map<string, (e: IpcMainEvent, ...args: any[]) => void> = new Map();

handle (method: string, fn: (e: IpcMainEvent, ...args: any[]) => any) {
if (method in this._invokeHandlers) {
if (this._invokeHandlers.has(method)) {
throw new Error(`Attempted to register a second handler for '${method}'`)
}
if (typeof fn !== 'function') {
throw new Error(`Expected handler to be a function, but found type '${typeof fn}'`)
}
this._invokeHandlers[method] = async (e, ...args) => {
this._invokeHandlers.set(method, async (e, ...args) => {
try {
(e as any).reply(await Promise.resolve(fn(e, ...args)))
} catch (err) {
(e as any).throw(err)
}
}
})
}

handleOnce (method: string, fn: Function) {
Expand All @@ -32,7 +28,7 @@ class IpcMain extends EventEmitter {
}

removeHandler (method: string) {
delete this._invokeHandlers[method]
this._invokeHandlers.delete(method)
}
}

Expand Down
4 changes: 2 additions & 2 deletions lib/browser/api/web-contents.js
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,8 @@ WebContents.prototype._init = function () {
event.reply = (result) => event.sendReply({ result })
event.throw = (error) => event.sendReply({ error: error.toString() })
this.emit('ipc-invoke', event, channel, ...args)
if (channel in ipcMain._invokeHandlers) {
ipcMain._invokeHandlers[channel](event, ...args)
if (ipcMain._invokeHandlers.has(channel)) {
ipcMain._invokeHandlers.get(channel)(event, ...args)
} else {
event.throw(`No handler registered for '${channel}'`)
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,4 @@
"git add filenames.auto.gni"
]
}
}
}
Loading

0 comments on commit 2d40e8a

Please sign in to comment.