Electron的 IPC响应未定义
我才刚接触Electron,我在学习IPC的工作原理。让我给你看看我的代码:
preload.js
import { contextBridge, ipcRenderer } from 'electron'
contextBridge.exposeInMainWorld('myApi', {
performAction(data) {
ipcRenderer.invoke('myChannel', data)
}
})
main.js
//-----------------------------------------------------
// IPC
//-----------------------------------------------------
ipcMain.handle('myChannel', (event, data) => {
return "hello from main: data: " + data
})
createWindow();
Vue组件
<script setup>
import { ref } from 'vue';
const ipcResponse = ref('')
async function invokeIpc()
{
try {
const response = await window.myApi.performAction("Hello from renderer")
ipcResponse.value = response
}
catch (error) {
console.log("Error: " + error)
}
}
</script>
<template>
<button @click="invokeIpc">Invoke Ipc</button>
<p>Response: {{ ipcResponse }}</p>
</template>
当我点击按钮时,什么也没发生,控制台没有错误,也没有响应。invokeIpc() 函数被调用,但响应未定义。
这段代码对吗?我是不是漏掉了什么?
解决方案
你其实已经很接近了,只是在preload里有一个小问题。
你的 performAction 调用了 ipcRenderer.invoke,但从不返回它返回的Promise:
contextBridge.exposeInMainWorld('myApi', {
performAction(data) {
ipcRenderer.invoke('myChannel', data) // this promise gets thrown away
}
})
所以当你在组件中执行 await window.myApi.performAction(...) 时,实际上是在等待 undefined,它解析为 undefined。这就是为什么 response 返回为空。
添加 return:
contextBridge.exposeInMainWorld('myApi', {
performAction(data) {
return ipcRenderer.invoke('myChannel', data)
}
})
这就是全部的修复。
你看到“什么也没发生,没有错误”的原因是,invoke实际上确实触发了,你的主处理程序也确实运行并返回了它的字符串。只是你在渲染进程等待它之前就把Promise放到了桥接层,因此没有抛出错误,也没有显示任何内容。
其他一切看起来都没问题。你的处理程序在 createWindow() 之前就已经注册,ipcMain.handle 返回一个普通字符串也不错,因为invoke会把它包装成一个Promise。invoke/handle是处理这类单次请求-响应的正确模式。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。