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

非深调用多变量场景Maximum call stack size exceeded报错求解

错误产生原因

报错的核心原因是无限递归导致调用栈溢出,原代码存在3个致命逻辑问题:

  • 函数末尾无条件执行this.noDuplicate(this.newCaption),没有设置任何递归终止条件:无论有没有检测到重名、无论生成的新标题是否合法,函数都会不停调用自身,直到超出调用栈的最大容量直接抛出错误。
  • 重名处理逻辑错位:检测到重名时,无后缀分支直接修改了已存在的旧书签的caption属性,有后缀分支仅给类属性this.newCaption赋值,没有把新生成的候选标题作为下一轮校验的核心目标,甚至在走无后缀分支时根本没给this.newCaption赋值,传入下一轮递归的参数是undefined。
  • 重名校验逻辑不闭环:即使修复了递归终止条件,现有逻辑遇到多重重名(比如已存在a、a.1、a.2,新书签标题为a)时,也无法正确生成不重复的a.3标题。
修复方案

直接用循环替代无终止条件的递归,同时修正重名处理的逻辑偏差,修复后的可运行代码如下:

newCaption: string;

noDuplicate(targetCaption: string): string {
  let candidateCaption = targetCaption;
  let hasAlerted = false;

  // 循环校验直到找到不重复的标题
  while (true) {
    // 检查当前候选标题是否与已有书签重名
    const isDuplicated = this.preferences.bookmarks.some(item => item.caption === candidateCaption);
    if (!isDuplicated) break;

    // 仅第一次检测到重名时弹出警告
    if (!hasAlerted) {
      this.alertService.warning("Caption is duplicate!");
      hasAlerted = true;
    }

    // 生成下一轮校验的候选标题,不修改已有书签的内容
    if (!candidateCaption.includes('.')) {
      candidateCaption = `${candidateCaption}.1`;
    } else {
      const dotPos = candidateCaption.indexOf('.');
      const prefix = candidateCaption.slice(0, dotPos);
      const suffixStr = candidateCaption.slice(dotPos + 1);
      const suffixNum = parseInt(suffixStr, 10);
      // 兜底处理后缀不是合法数字的场景
      const nextSuffix = Number.isNaN(suffixNum) ? 1 : suffixNum + 1;
      candidateCaption = `${prefix}.${nextSuffix}`;
    }
  }

  this.newCaption = candidateCaption;
  return candidateCaption;
}

修复点说明

  • 移除了无终止条件的递归,改用while循环做重名校验,从根源上避免调用栈溢出问题,逻辑更易调试
  • 全程不修改已有书签的标题属性,所有候选标题仅用于当前待校验的新书签,不会污染旧数据
  • 增加了后缀非数字的兜底逻辑,遇到test.abc这类异常格式的重名项时,会自动生成合法的test.1作为新标题,不会出现NaN的异常值
  • 警告提示仅在第一次检测到重名时触发,不会重复弹出
  • 只要检测到当前候选标题无重名就立刻终止流程,没有多余的性能损耗

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 17:57:27