## 使用 Electron 在兩個進程 (主進程和渲染進程) 之間進行通訊
通過 ipc(進程間通信)模塊允許您在主進程和渲染進程之間發送和接收同步和異步消息.
這個模塊有一個版本可用于這兩個進程: ipcMain 和 ipcRenderer.
在瀏覽器中查看 [main process](http://electron.atom.io/docs/api/ipc-main)?和 [renderer proces](http://electron.atom.io/docs/api/ipc-renderer/)?的完整 API 文檔.
### 異步消息
`支持: Win, macOS, Linux | 進程: Both`
使用 ipc 以異步方式在進程之間發送消息是首選方法, 因為它會在完成時返回, 而不會阻止同一進程中的其他操作.
此示例將從此進程(渲染器)發送異步消息 "Ping" 到主進程, 然后主進程回答 "Pong".

渲染器進程
```
sendAsyncMsg () {
const {ipcRenderer} = require('electron')
ipcRenderer.send('asynchronous-message', 'ping')
ipcRenderer.on('asynchronous-reply', (event, arg) => {
this.asyncMsg = `異步消息回復: ${arg}`
})
},
```
主進程
```
const {ipcMain} = require('electron')
ipcMain.on('asynchronous-message', (event, arg) => {
event.sender.send('asynchronous-reply', 'pong')
})
```
### 同步消息
`支持: Win, macOS, Linux | 進程: Both`
您可以使用 ipc 模塊在進程之間發送同步消息. 但請注意, 此方法的同步特性意味著它在完成任務時會阻止其他操作.
此示例將從此進程(渲染器)發送同步消息 "Ping" 到主進程, 然后主進程回答 "Pong".

渲染器進程
```
sendSyncMsg () {
const {ipcRenderer} = require('electron')
const reply = ipcRenderer.sendSync('synchronous-message', 'ping')
this.syncMsg = `同步消息回復: ${reply}`
},
```
主進程
```
const {ipcMain} = require('electron')
ipcMain.on('synchronous-message', (event, arg) => {
event.returnValue = 'pong'
})
```
### 與隱藏窗口通信
通常的做法是創建一個新的不可見瀏覽器窗口(渲染器進程), 以便在不影響主應用程序窗口中的性能的情況下運行任務.
在這個示例中, 我們使用 <code>remote</code> 模塊從這個渲染器進程創建一個新的不可見的瀏覽器窗口. 當新頁面加載時, 我們用 <code>ipc</code> 發送一個消息給正在監聽的新窗口.
然后新窗口計算階乘并發送要由此接收的結果到原始窗口并添加到上面的頁面中.

渲染器進程
```
cumInvisible () {
const {BrowserWindow} = require('electron').remote
const ipcRenderer = require('electron').ipcRenderer
const windowID = BrowserWindow.getFocusedWindow().id
let invisPath
if (process.env.NODE_ENV === 'development') {
invisPath = 'http://localhost:8080#/invisibleWin'
} else {
invisPath = `file://${__dirname}/index.html#/invisibleWin`
}
const win = new BrowserWindow({
width: 400,
height: 400,
show: false,
webPreferences: {
nodeIntegration: true
}
})
win.loadURL(invisPath)
win.webContents.on('did-finish-load', () => {
const input = 100
win.webContents.send('compute-factorial', input, windowID)
})
ipcRenderer.on('factorial-computed', (event, input, output) => {
this.inMsg = `${input} 的階乘是 ${output}`
})
}
```
隱藏窗口腳本
```
const ipc = require('electron').ipcRenderer
const BrowserWindow = require('electron').remote.BrowserWindow
ipc.on('compute-factorial', function (event, number, fromWindowId) {
const result = factorial(number)
const fromWindow = BrowserWindow.fromId(fromWindowId)
fromWindow.webContents.send('factorial-computed', number, result)
console.log(result)
window.close()
})
function factorial (num) {
if (num === 0) return 1
return num * factorial(num - 1)
}
```