You need to enable JavaScript to run this app. Electron使用invoke/handle时如何将preload.js数据传到renderer.js
优惠活动
大模型
产品
解决方案
定价
更多

Electron使用invoke/handle时如何将preload.js数据传到renderer.js

问题根源

你当前控制台打印的data为undefined,核心问题出在Main.js的ipcMain.handle回调没有返回完整的Promise链,导致主进程处理完结果后无法把值回传给IPC调用端,另外你的目录递归逻辑也存在小问题会导致返回的结构嵌套Promise对象。


修复步骤

1. 修复Main.js的handle逻辑

给dialog.showOpenDialog调用前加return,把整个异步链返回给IPC handle:

ipcMain.handle(HANDLE_FETCH_DATA, (events) => {
    // 新增return把Promise链返回给IPC调用端
    return dialog.showOpenDialog(win, {
        properties: ['openDirectory']
    }).then(result => {
        if (result.canceled === true) return null; // 取消选择返回明确空值,方便渲染层判断
        const filePath = result.filePaths[0]
        return crawlDirectory(filePath)
    })
})

2. 确认preload.js上下文桥配置正确

确保你的loadDirectory方法是通过contextBridge暴露给渲染进程的,完整配置参考:

const { contextBridge, ipcRenderer } = require('electron')
// 统一管理IPC通道常量,避免拼写错误
const HANDLE_FETCH_DATA = 'fetch-directory-data'

contextBridge.exposeInMainWorld('app', {
    filesApi: {
        loadDirectory: (channel) => ipcRenderer.invoke(channel)
    }
})

3. 渲染层增加异常处理

renderer.js中增加错误捕获逻辑,处理取消选择、目录读取失败的场景:

// 渲染层也要定义和主进程、预加载层一致的IPC通道常量
const HANDLE_FETCH_DATA = 'fetch-directory-data'

async function loadDirectoryFolders() {
    try {
        const data = await app.filesApi.loadDirectory(HANDLE_FETCH_DATA)
        if (!data) {
            console.log('用户取消了目录选择')
            return
        }
        console.log('获取到的目录结构:', data)
        // 此处直接使用data做后续渲染逻辑即可
    } catch (err) {
        console.error('加载目录失败:', err)
    }
}

4. 优化crawlDirectory递归逻辑

你当前递归子目录时直接push了crawlDirectory返回的Promise,会导致最终返回的children字段嵌套Promise对象,改为异步await处理即可:

// 改为async函数,无需手动封装Promise
const crawlDirectory = async (dir) => {
    const folderName = path.basename(dir);
    const model = {
        id: short.generate(),
        name: folderName,
        children: [],
        toggled: false,
        active: false,
        loading: false,
        decorators: {},
        animations: []
    };
    const folders = fs.readdirSync(dir).filter(file => file !== '.DS_Store');
    for (const folder of folders) {
        const next = path.join(dir, folder);
        const isDirectory = fs.lstatSync(next).isDirectory();
        if (isDirectory) {
            // await拿到递归返回的实际对象再push
            model.children.push(await crawlDirectory(next))
        } else {
            model.children.push({ name: path.basename(next) })
        }
    }
    return model
}

内容的提问来源于stack exchange,提问作者Nellz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 13:24:00