Electron.js中Promise .then()失效问题排查求助
Electron渲染进程Promise未等待主进程保存完成问题排查
问题根源
你当前的写法存在两个核心问题:
- 渲染进程中的Promise在调用
window.electron.saveJson(dataArray)后立刻执行了resolve,完全没有等待主进程的文件选择、写入等异步操作完成,导致then里的成功提示会提前触发,和文件实际保存状态脱节。 - 主进程执行完文件保存操作后,没有把结果(成功/失败)通知回渲染进程,渲染进程无法感知异步操作的结束时机。
修复方案
需要通过IPC双向通信实现渲染进程和主进程的异步状态同步:
- 主进程在文件保存完成(或失败)后,向渲染进程发送结果通知。
- 渲染进程的保存逻辑需要等待主进程的通知后,再执行成功提示或错误处理。
修改后的代码
主进程(main.js)
const { ipcMain, dialog, fs } = require('electron'); ipcMain.on("saveJson", (event, data) => { saveJSONToFile(event, data); }); async function saveJSONToFile(event, data) { const options = { title: "Save JSON File", defaultPath: "data.json", filters: [{ name: "JSON Files", extensions: ["json"] }], }; try { const result = await dialog.showSaveDialog(win, options); if (!result.canceled) { const filePath = result.filePath; const jsonData = JSON.stringify(data); // 使用Promise版的writeFile替代回调,简化异步逻辑 await fs.promises.writeFile(filePath, jsonData, "utf-8"); // 通知渲染进程保存成功 event.sender.send("saveJsonResult", { success: true, message: "JSON data saved successfully!" }); } else { // 用户取消保存时通知渲染进程 event.sender.send("saveJsonResult", { success: false, message: "Save operation canceled." }); } } catch (err) { console.error(err); // 通知渲染进程保存失败 event.sender.send("saveJsonResult", { success: false, message: err.message }); } }
渲染进程(renderer.js)
function concatAndSave() { let dataArray = jsonArrLeft.concat(jsonArrRight); // 创建Promise,等待主进程的结果通知 const savePromise = new Promise((resolve, reject) => { // 监听主进程返回的一次性结果通知,避免重复绑定 window.electron.ipcRenderer.once("saveJsonResult", (_, result) => { if (result.success) { resolve(result.message); } else { reject(new Error(result.message)); } }); // 向主进程发送保存请求 window.electron.saveJson(dataArray); }); savePromise.then((info) => { closeSaveConfigWindow(); const currentTime = new Date(); textArea.value += info + "[" + currentTime.getHours() + ":" + currentTime.getMinutes() + ":" + currentTime.getSeconds() + "]" + "\n\n"; textArea.scrollTop = textArea.scrollHeight; removeStars(tableLeft.querySelector("#mf-table-body"), unsavedLeft); removeStars(tableRight.querySelector("#mf-table-right"), unsavedRight); }).catch((err) => { // 处理保存失败或取消的场景 console.error(err); alert(`Save failed: ${err.message}`); }); }
关键说明
- 主进程用
async/await替代嵌套Promise和回调,简化异步逻辑的同时提升可读性。 - 渲染进程通过
ipcRenderer.once监听一次性事件,避免多次绑定导致的内存泄漏。 - 新增了错误处理分支,覆盖用户取消保存、文件写入失败等场景,让交互逻辑更完整。
内容的提问来源于stack exchange,提问作者bkh6722
相关产品推荐
相关产品推荐

