Googling says you can add a callback to it, but the documentation just says "arg1, arg2, arg3" etc.
They also have sendSync, but I'd prefer not to block while my event is being sent [we're trying to do as much work through the browser as possible, because writing client code in node, seems a little daft].
If the creators have a sendSync, then surely they have a version with callbacks, or better yet promises.
Some examples of things i'd like to be able to do:
//callback
ipcRenderer.send('anaction', '[1, 2, 3]', function() { console.log('done anaction') });
//promise
ipcRenderer.send('anaction', '[1, 2, 3]')
.then(function() { console.log('done anaction') });
//sync exists, but it blocks. I'm looking for a non-blocking function
ipcRenderer.sendSync('anacount', '[1, 2, 3]')
console.log('done anaction');
The ipcRenderer module is an EventEmitter. It provides a few methods so you can send synchronous and asynchronous messages from the render process (web page) to the main process. You can also receive replies from the main process.
To send a message back to the renderer you would use: win. webContents. send('asynchronous-message', {'SAVED': 'File Saved'});
IPC channels In Electron, processes communicate by passing messages through developer-defined "channels" with the ipcMain and ipcRenderer modules. These channels are arbitrary (you can name them anything you want) and bidirectional (you can use the same channel name for both modules).
In case anybody is still looking for an answer to this question in 2020, a better way to handle replying from the main thread back to the renderer is not to use send
at all, but rather to use ipcMain.handle
and ipcRenderer.invoke
, which make use of async
/await
and return Promises:
main.js
import { ipcMain } from 'electron';
ipcMain.handle('an-action', async (event, arg) => {
// do stuff
await awaitableProcess();
return "foo";
}
renderer.js
import { ipcRenderer } from 'electron';
(async () => {
const result = await ipcRenderer.invoke('an-action', [1, 2, 3]);
console.log(result); // prints "foo"
})();
ipcMain.handle
and ipcRenderer.invoke
are compatible with contextBridge
, allowing you to expose an API to ask the main thread for data from the renderer thread and do something with it once it comes back.
main.js
import { ipcMain, BrowserWindow } from 'electron';
ipcMain.handle('an-action', async (event, arg) => {
// do stuff
await awaitableProcess();
return "foo";
}
new BrowserWindow({
...
webPreferences: {
contextIsolation: true,
preload: "preload.js" // MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY if you're using webpack
}
...
});
preload.js
import { ipcRenderer, contextBridge } from 'electron';
// Adds an object 'api' to the global window object:
contextBridge.exposeInMainWorld('api', {
doAction: async (arg) => {
return await ipcRenderer.invoke('an-action', arg);
}
});
renderer.js
(async () => {
const response = await window.api.doAction([1,2,3]);
console.log(response); // we now have the response from the main thread without exposing
// ipcRenderer, leaving the app less vulnerable to attack
})();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With