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

Electron.js中Promise .then()失效问题排查求助

Electron渲染进程Promise未等待主进程保存完成问题排查

问题根源

你当前的写法存在两个核心问题:

  1. 渲染进程中的Promise在调用window.electron.saveJson(dataArray)后立刻执行了resolve,完全没有等待主进程的文件选择、写入等异步操作完成,导致then里的成功提示会提前触发,和文件实际保存状态脱节。
  2. 主进程执行完文件保存操作后,没有把结果(成功/失败)通知回渲染进程,渲染进程无法感知异步操作的结束时机。

修复方案

需要通过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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 23:46:25