Electron桌面Bybit交易应用同步获取主进程响应问题求助
解决Electron渲染进程同步获取主进程余额数据的问题
你的核心问题是想用同步逻辑等待主进程的响应,但Electron的ipcRenderer.sendSync不适合这种场景(会阻塞主线程,且无法传递函数),同时原来的事件监听方式无法直接让代码等待结果。下面是符合安全规范的解决方案:
步骤1:修改主进程(main.js)
用ipcMain.handle替代ipcMain.on,它支持直接返回异步结果给渲染进程,无需手动发送回复:
const { app, BrowserWindow, ipcMain, Menu } = require('electron'); const path = require('path'); const CryptoJS = require('crypto-js'); const axios = require('axios'); let win; async function createWindow() { win = new BrowserWindow({ width: 385, height: 200, titleBarStyle: 'hidden', webPreferences: { nodeIntegration: false, contextIsolation: true, enableRemoteModule: false, preload: path.join(app.getAppPath(), 'preload.js'), backgroundThrottling: false, }, }); win.loadFile(path.join(__dirname, './index.html')); win.setAlwaysOnTop(true, 'screen'); } app.on('ready', createWindow); // 改用handle,直接返回异步结果 ipcMain.handle('getBalance', async () => { const apiKey = ''; const secret = ''; const timestamp = Date.now().toString(); const params = { api_key: apiKey, timestamp: timestamp, }; let orderedParams = ''; Object.keys(params) .sort() .forEach(function (key) { orderedParams += key + '=' + params[key] + '&'; }); orderedParams = orderedParams.substring(0, orderedParams.length - 1); var hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, secret); hmac.update(orderedParams); const sign = hmac.finalize().toString(CryptoJS.enc.Hex); const res = await axios.get(`https://api.bybit.com/v2/private/wallet/balance?&api_key=${apiKey}&sign=${sign}×tamp=${timestamp}`); return res.data.result.USDT.equity.toFixed(2); });
步骤2:修改预加载脚本(preload.js)
通过contextBridge暴露一个返回Promise的getBalance方法,内部用ipcRenderer.invoke和主进程通信:
const { contextBridge, ipcRenderer } = require('electron'); contextBridge.exposeInMainWorld('api', { // 封装getBalance方法,返回Promise getBalance: () => ipcRenderer.invoke('getBalance') });
步骤3:修改渲染进程脚本(script.js)
把getBalance改成异步函数,用await等待结果返回后再渲染:
const getBalance = async () => { try { // 等待主进程返回余额 const balance = await window.api.getBalance(); const myBalance = '$' + balance; document.querySelector('.myBalance').textContent = `My Balance: ${myBalance}`; } catch (error) { // 处理请求失败的情况 console.error('获取余额失败:', error); document.querySelector('.myBalance').textContent = 'My Balance: 加载失败'; } }; // 调用异步函数 getBalance();
关键说明
- 为什么不用
sendSync?sendSync会阻塞主进程(直到收到回复),严重影响应用性能,而且传递的参数必须是Electron的可克隆对象(函数、DOM元素等无法克隆,这也是你之前报错的原因)。 ipcMain.handle+ipcRenderer.invoke是Electron官方推荐的请求-响应式通信方式,天然支持异步,符合安全规范(contextIsolation开启时依然可用)。- 用
async/await可以让代码看起来像同步执行,同时不会阻塞渲染进程。
内容的提问来源于stack exchange,提问作者Eugene1111
相关产品推荐
相关产品推荐

