英文:
Issue with ipcMain.handle() not returning any value to ipcRenderer.invoke()
问题
这是与问题相关的3个文件的翻译:
main.ts(不是整个文件):
app.whenReady().then(() => {
ipcMain.on("set-credentials", (event, args: object) => {
encryptedCredentials = safeStorage.encryptString(JSON.stringify(args));
});
ipcMain.handle("get-credentials", async (event, args: null) => {
const decryptedCredentials = await JSON.parse(
safeStorage.decryptString(encryptedCredentials)
);
return decryptedCredentials;
});
createWindow();
});
preload.ts(整个文件):
import { ipcRenderer, contextBridge } from "electron";
contextBridge.exposeInMainWorld("electronAPI", {
setStoredCredentials: async (args: object) =>
await ipcRenderer.send("set-credentials", args),
getStoredCredentials: () => {
ipcRenderer.invoke("get-credentials");
},
});
Login.tsx(不是整个文件):
const setStoredCredentials = async (e: any, service: string) => {
e.preventDefault();
window.electronAPI.setStoredCredentials({
service,
username: e.target[0].value,
password: e.target[1].value,
});
setTimeout(() => {
window.electronAPI.getStoredCredentials().then(
(data: object) => { console.log(data); } //测试
)
}, 1000)
};
(该 Electron 应用程序使用 React)
解决问题时,我尝试使用 ipcMain.on
和 ipcRenderer.sendSync
与 event.returnValue
,但都没有奏效。当前代码会引发以下错误:
caught TypeError: Cannot read properties of undefined (reading 'then')
而我尝试的其他方法要么产生相同的错误,要么返回 undefined
值。
英文:
So, I struggled with this problem for 2 days, looking in the API documentation of Electron.js and various sites and you guys are my last hope:
Here are the 3 files related to the issue:
main.ts (not the entire file):
app.whenReady().then(() => {
ipcMain.on("set-credentials", (event, args: object) => {
encryptedCredentials = safeStorage.encryptString(JSON.stringify(args));
});
ipcMain.handle("get-credentials", async (event, args: null) => {
const decryptedCredentials = await JSON.parse(
safeStorage.decryptString(encryptedCredentials)
);
return decryptedCredentials;
});
createWindow();
});
preload.ts (entire file):
import { ipcRenderer, contextBridge } from "electron";
contextBridge.exposeInMainWorld("electronAPI", {
setStoredCredentials: async (args: object) =>
await ipcRenderer.send("set-credentials", args),
getStoredCredentials: () => {
ipcRenderer.invoke("get-credentials");
},
});
Login.tsx (not the entire file):
const setStoredCredentials = async (e: any, service: string) => {
e.preventDefault();
window.electronAPI.setStoredCredentials({
service,
username: e.target[0].value,
password: e.target[1].value,
});
setTimeout(() => {
window.electronAPI.getStoredCredentials().then(
(data: object) => { console.log(data); } //testing
)
}, 1000)
};
(the electron app features React)
So to solve the issue I tried using ipcMain.on
and ipcRenderer.sendSync
with event.returnValue
, didn't work either.
I get the following error with the current code:
caught TypeError: Cannot read properties of undefined (reading 'then')
and the other methods I tried either gave the same error or an undefined
value.
答案1
得分: 3
双向IPC在渲染进程中需要使用async/await
。IPC可能会花费一些时间。如果没有async/await
,原始调用只会得到一个Promise
。
尝试在setStoredCredentials
和getStoredCredentials
两个函数中都添加await
。
const setStoredCredentials = async (e: any, service: string) => {
e.preventDefault();
await window.electronAPI.setStoredCredentials({
service,
username: e.target[0].value,
password: e.target[1].value,
});
setTimeout(() => {
await window.electronAPI.getStoredCredentials().then(
(data: object) => { console.log(data); } //测试
)
}, 1000)
};
如果上面的代码有效,可以移除setTimeout
。
英文:
Two-way IPC needs async/await
in the renderer process. IPC may spend a bit time. Without async/await
, the original call just gets a Promise
.
Try to add await
to both setStoredCredentials
and getStoredCredentials
.
const setStoredCredentials = async (e: any, service: string) => {
e.preventDefault();
await window.electronAPI.setStoredCredentials({
service,
username: e.target[0].value,
password: e.target[1].value,
});
setTimeout(() => {
await window.electronAPI.getStoredCredentials().then(
(data: object) => { console.log(data); } //testing
)
}, 1000)
};
If the code above works, setTimeout
can be removed.
答案2
得分: 0
当我在 main.ts
中在返回之前使用 console.log()
打印要返回的值时,它正常工作。
另外,cryptedCredentials
变量声明如下:let cryptedCredentials: Buffer;
英文:
just a small clarification:
when I do a console.log()
of the value to return in main.ts
before returning it it works just fine.
Also the cryptedCredentials
var is declared as follows: let cryptedCredentials: Buffer;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论