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

Electron 27.3.11中Promise执行中断问题排查求助

Electron 27.3.11中Promise永久挂起排查方案

问题场景

使用Electron 27.3.11版本时,代码执行到await this.createTalents("silent")位置会永久挂起,createTalents内的初始化日志完全无法输出。单元测试无异常,但进程运行时会出现Promise在不同await位置随机挂起的现象:添加日志或大闭包会提前触发挂起,移除则延后,无内存不足报错,内存检测数据显示正常:

{
  jsHeapSizeLimit: 3760000000,
  totalJSHeapSize: 68000000,
  usedJSHeapSize: 56800000,
}

核心代码片段:

async init({ items } = {}) {
  // 此日志能正常输出
  if (Game.config.debug) console.log("[CharacterBase] Initializing...");
  if (!this.skills) this.createSkills();

  // this.talents === null
  if (!this._talents) await this.createTalents("silent");
  if (!this.attributes) this.createAttributes();
  if (!this.subtitle) this.createSubtitle();
  if (!this.doll) this.createDoll();
  if (!this.filepath) this.createFilepath();

  return super.init({ items });
}

async createTalents(option) {
  // 此日志无法输出
  if (Game.config.debug) console.log("[CharacterBase] Creating talents...");
  this._talents = [];

  for (const key of ["raceObject", "secondaryObject", "tradeObject"])
    for (const k of this[key]?.talents ?? [])
      await this.createTalent(k, option);

  for (const talent of Object.values(Game.TALENTS).filter(
    (talent) => !talent.requirements,
  ))
    await this.createTalent(talent.key, option);

  return this._talents;
}

排查方向与解决方案

  • 检查主线程事件循环阻塞:Electron渲染进程是单线程模型,任何长时间同步操作(比如大量同步IO、死循环、复杂同步计算)都会导致微任务队列无法处理,Promise永久pending。可以用process.hrtime()在关键节点打点计时,或者通过开发者工具的Performance面板录制执行流程,定位耗时超标的阻塞任务。
  • 捕获未处理的Promise异常:如果createTalent内部抛出异常但未被捕获,Promise会静默reject,表现为挂起。给await this.createTalents("silent")添加try/catch,或者全局监听未处理拒绝事件:
    process.on('unhandledRejection', (reason, promise) => {
      console.error('未处理的Promise拒绝:', promise, '原因:', reason);
    });
    
  • 排查IPC通信异常:如果createTalent涉及主渲染进程IPC调用(比如ipcRenderer.invoke),需确认主进程是否正常响应,是否存在IPC消息丢失或主进程自身阻塞的情况。可以在IPC回调中添加日志,或临时用ipcRenderer.sendSync替换invoke测试(注意sendSync会阻塞主线程,仅用于排查)。
  • 逐步简化代码定位问题点:注释掉createTalents内所有await this.createTalent调用,只保留初始化日志,验证是否能正常执行;再逐步恢复代码,定位触发挂起的具体逻辑。
  • 验证Electron版本已知问题:Electron 27.x属于旧稳定版,可能存在已修复的微任务/事件循环相关bug。尝试升级到27.x最新补丁版,或降级到26.x稳定版测试,看问题是否消失。
  • 释放主线程资源:如果createSkills、createAttributes等同步方法存在大量计算或DOM操作,会占用主线程导致后续微任务无法调度。用setImmediate或Promise.resolve().then()包裹这些同步逻辑,释放主线程。
  • 查看活跃句柄与请求:在开发者工具控制台执行console.log(process._getActiveHandles(), process._getActiveRequests()),查看是否存在未完成的句柄或请求,定位潜在阻塞源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 18:14:55