Reputation: 13
ipcRenderer.sendSync
may block the whole renderer process. ipcRenderer.send
need use ipcRenderer.on
to listen for the asynchronous return of events.
So is there a way of communicating that data can be returned as a callback directly where it was requested?
It might look something like this: ipcRenderer.sendAsync('eventName', args, callback)
, Or by other means.
ipcRenderer.on("onMessage", (e, {cbName, data}) => {
switch (cbName) {
case 'foo1':
foo1(data)
break
case 'foo2':
foo2(data)
break
case 'foo3':
foo2(data)
break
// more
default:
break
}
})
ipcRenderer.send("message", { cbName, /* other args */ })
Upvotes: 0
Views: 815
Reputation: 11
what you need is ipcMain.handle() and ipcRenderer.invoke() this will return a promise back to renderer.
// Main process
ipcMain.handle('my-invokable-ipc', async (event, ...args) => {
const result = await somePromise(...args)
return result
})
// Renderer process
async () => {
const result = await ipcRenderer.invoke('my-invokable-ipc', arg1, arg2)
// ...
}
For further info https://www.electronjs.org/docs/api/ipc-main#ipcmainhandlechannel-listener
Upvotes: 1
Reputation: 10199
What you're asking for, if I understand it correctly, is to pass a callback from the renderer process to the main process and have the handler in main call into it with the response rather than sending it back.
so rather than doing this:
main.js:
ipcMain.on("message", (e, arg) => {
e.sender.send("onMessage", "response");
});
renderer.js:
ipcRenderer.send("message", 1);
ipcRenderer.on("onMessage", (e, response) => { });
you want to do this:
main.js:
ipcMain.on("message", (e, arg, callback) => {
callback("response");
});
renderer.js:
function callback(response) { }
ipcRenderer.send("message", 1, callback);
Then no, you can't do that because you can't pass functions across processes like this. Even if you .toString()
the function and then recreate the function in the main process via new Function(...)
, you would be executing it in the context of the main process, not the renderer, and presumably you'd want to execute it in the renderer process.
Using e.sender.send(...)
is the idiomatic way of sending messages back to the other process, and you shouldn't shy away from it.
Upvotes: 0