canvas
canvas

Reputation: 13

How can the electron framework enable communication like an Ajax request?

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

Answers (2)

satvikbsvr
satvikbsvr

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

pushkin
pushkin

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

Related Questions