electron中ipcRenderer.invoke、ipcRenderer.on、ipcRenderer.send、ipcRenderer.sendSync作用與區別
IPC 渲染進程與主進程通信方法解析
ipcRenderer
的這幾個方法作用不完全相同,它們適用于不同的通信場景,核心區別在于通信方向、是否需要響應以及同步 / 異步特性。下面詳細說明:
1. ipcRenderer.send(channel, ...args)
-
作用:從渲染進程向主進程發送異步消息(單向通信),不需要返回結果。
-
特點:
-
發送后立即返回,不等待主進程處理。
-
主進程通過
ipcMain.on(channel, (event, ...args) => { ... })
接收。 -
適合只需要通知主進程執行操作,不需要結果的場景。
-
-
示例:
// 渲染進程ipcRenderer.send('open-file', '/path/to/file');// 主進程ipcMain.on('open-file', (event, path) => {fs.openSync(path, 'r');});
2. ipcRenderer.on(channel, listener)
-
作用:在渲染進程中監聽主進程發送的特定頻道消息(被動接收)。
-
特點:
-
用于接收主進程通過
webContents.send(channel, ...args)
發送的消息。 -
是 “接收消息” 的方法,而非 “發送消息”。
-
-
示例:
// 渲染進程(監聽主進程消息)ipcRenderer.on('file-opened', (event, content) => {console.log('文件內容:', content);});// 主進程(發送消息給渲染進程)mainWindow.webContents.send('file-opened', '文件內容...');
3. ipcRenderer.invoke(channel, ...args)
-
作用:從渲染進程向主進程發送異步請求,并等待主進程返回結果(類似 HTTP 的請求 - 響應模式)。
-
特點:
-
返回一個
Promise
,可配合async/await
使用。 -
主進程通過
ipcMain.handle(channel, async (event, ...args) => { ... })
處理并返回結果。 -
適合需要主進程處理后返回數據的場景(如讀取文件、調用系統 API 等)。
-
-
示例:
// 渲染進程async function readFile() {const content = await ipcRenderer.invoke('read-file', '/path/to/file');
console.log('文件內容:', content);}// 主進程ipcMain.handle('read-file', async (event, path) => {return fs.readFileSync(path, 'utf8'); // 返回結果給渲染進程});
4. ipcRenderer.sendSync(channel, ...args)
-
作用:從渲染進程向主進程發送同步請求,會阻塞渲染進程直到主進程返回結果。
-
特點:
-
同步執行,會卡住渲染進程(可能導致界面卡頓),不推薦頻繁使用。
-
主進程通過
ipcMain.on(channel, (event, ...args) => { event.returnValue = ... })
返回結果。 -
適合極少數必須同步獲取結果的場景。
-
-
示例:
// 渲染進程(同步等待結果)const content = ipcRenderer.sendSync('read-file-sync', '/path/to/file');console.log('文件內容:', content);// 主進程ipcMain.on('read-file-sync', (event, path) => {event.returnValue = fs.readFileSync(path, 'utf8'); // 通過 returnValue 返回});
核心區別總結
方法 | 通信方向 | 同步 / 異步 | 是否需要返回結果 | 主進程處理方式 |
---|---|---|---|---|
send | 渲染 → 主進程 | 異步 | 不需要 | ipcMain.on |
on | 主進程 → 渲染 | 異步 | 接收結果 | 配合 webContents.send |
invoke | 渲染 → 主進程 | 異步 | 需要(請求 - 響應) | ipcMain.handle |
sendSync | 渲染 → 主進程 | 同步 | 需要(阻塞) | ipcMain.on + event.returnValue |
最佳實踐
-
大多數場景優先使用
invoke
(異步請求 - 響應)和send
(單向通知)。 -
避免使用
sendSync
,因其會阻塞渲染進程,影響用戶體驗。 -
主進程向渲染進程發送消息時,用
webContents.send
配合渲染進程的ipcRenderer.on
。