You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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}&timestamp=${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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 02:35:22