如何向IPC渲染器发送添加回调 [英] How to add a callback to ipc renderer send

查看:364
本文介绍了如何向IPC渲染器发送添加回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Google搜索可以添加回调,但是文档中仅显示"arg1,arg2,arg3"等.

它们也具有sendSync,但是我不希望在发送事件时不阻塞[我们正在尝试通过浏览器进行尽可能多的工作,因为在node中编写客户端代码似乎有些愚蠢]

如果创建者具有sendSync,则可以肯定的是,他们具有带回调的版本,或者更好的是应许.

一些我想做的事例子:

 //回调ipcRenderer.send('anaction','[1,2,3]',function(){console.log('done anaction')});//承诺ipcRenderer.send('anaction','[1,2,3]').then(function(){console.log('done anaction')});//sync存在,但是被阻止了.我正在寻找一种非阻塞功能ipcRenderer.sendSync('anacount','[1,2,3]')console.log('done anaction'); 

解决方案

如果有人在2020年仍在寻找该问题的答案,则最好不要使用处理从主线程返回渲染器的更好方法.完全发送,而是使用 ipcMain.handle ipcRenderer.invoke ,它使用 async / await 并返回Promises:

main.js

 从"electron"导入{ipcMain};ipcMain.handle('an-action',async(event,arg)=> {//做东西等待awaitableProcess();返回"foo";} 

renderer.js

 从"electron"导入{ipcRenderer};(异步()=> {const result = await ipcRenderer.invoke('an-action',[1,2,3]);console.log(result);//打印"foo"})(); 


ipcMain.handle ipcRenderer.invoke

preload.js

 从'electron'导入{ipcRenderer,contextBridge};//将对象"api"添加到全局窗口对象:contextBridge.exposeInMainWorld('api',{doAction:异步(arg)=>{返回等待ipcRenderer.invoke('an-action',arg);}}); 

renderer.js

 (async()=> {const response =等待window.api.doAction([1,2,3]);console.log(response);//现在,我们有来自主线程的响应,而没有暴露//ipcRenderer,使应用程序更不容易受到攻击})(); 

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');

解决方案

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    
})();

这篇关于如何向IPC渲染器发送添加回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆