【问题标题】:How to pass ipcRenderer.invoke handler answer to electron renderer process using preload.js如何使用 preload.js 将 ipcRenderer.invoke 处理程序答案传递给电子渲染器进程
【发布时间】:2020-11-04 19:45:26
【问题描述】:

我正在编写一个 CRA + Electron 应用程序,我需要使用 ipcRenderer.invoke 进行进程间通信。我能够使 ipcRenderer.send 和 ipcRender.on 在 contextIsolation 模式下工作,但 ipcRender.invoke 没有运气。由于某种我不明白的原因,我无法以任何形式(承诺或价值)将处理程序响应返回给渲染器,我得到的只是“未定义”值。

preload.js

const { contextBridge, ipcRenderer } = require('electron');

 // whitelist channels
const validChannels = ["toMain", "fromMain", "invokeMain"]
// Expose protected methods that allow the renderer process to use
// the ipcRenderer without exposing the entire object
contextBridge.exposeInMainWorld(
    "apiKey", {
        sendApi: (channel, ...args) => {
            if (validChannels.includes(channel)) {
                ipcRenderer.send(channel, ...args);
            }
        },
        onApi: (channel, func) => {
            if (validChannels.includes(channel)) {
                // Deliberately strip event in func as it includes `sender` 
                ipcRenderer.on(channel, (event, ...args) => func(...args));
            }
        },
        invokeApi: (channel, ...args) => {
            if ( validChannels.includes(channel) ) {
                ipcRenderer.invoke(channel, ...args).then( (value) =>{
                    console.log('apiKey.invokeApi:', value);
                    return value;
                });
            };
        },
    }
);

main.js

ipcMain.handle('invokeMain', async (event, ...arg) => {
  console.log ('invokeMain received arg:', ...arg);
  let response = 'pong';  
  //return new Promise( (resolve) => setTimeout(resolve(response), 2000), (reject) => reject() );
  let prom = new Promise( (resolve) => setTimeout(resolve(response), 2000), (reject) => reject() );
  let result = await prom;
  console.log ('invokeMain response to Renderer:', prom);
  return prom;
//return result;  
})

Main.js output

渲染器.js

//Invoke Main
let invokeMessage = "ping";
async function send (invokeMessage) {
    console.log('ipcMain.handle response:', window.apiKey.invokeApi('invokeMain', invokeMessage));
//    let response = await window.apiKey.invokeApi('invokeMain', invokeMessage)
//    console.log('ipcMain.handle response:', response);
//    response.then((value) =>{
//        console.log('ipcMain.handle response:', value);
//    });
};
send(invokeMessage);

Renderer.js output

谁能指出我做错了什么?提前致谢

【问题讨论】:

    标签: electron preload preloadjs ipcrenderer


    【解决方案1】:

    我通过从预加载而不是值返回调用方法的承诺来使其工作。

    在我的预加载中:

    invoke: (channel: string, data: any) => {
        // whitelist channels
        let validChannels = ["myValidChannel"];
        if (validChannels.includes(channel)) {
            return ipcRenderer.invoke(channel, data);
        }
    },
    

    并直接在渲染器中处理:

    try {
        const result = await window.myIpcRenderer.invoke("myValidChannel", data)
    } catch (err) {
        console.log(err)
    }
    

    【讨论】:

      猜你喜欢
      • 2021-04-26
      • 1970-01-01
      • 2019-12-11
      • 1970-01-01
      • 2019-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多