如何解决JavaScript触发Maximum call stack size exceeded报错问题
问题定位
触发Maximum call stack size exceeded栈溢出报错的核心原因是同步无限递归:
原代码在setTimeout注册完异步延迟任务后,立刻同步调用了start(),这行调用不会等待3秒延迟结束,会直接触发下一轮start()执行;每一轮start()都会重复「注册异步任务 -> 同步调用自身」的逻辑,函数反复压入调用栈却永远没有出栈机会,瞬间就会超出调用栈的最大容量限制。
除此之外代码还存在一个API拼写错误:JS内置延迟方法的正确写法是setTimeout,原代码错写为setTimeOut(末尾的字母O错误大写),即便解决递归问题也会触发「方法未定义」报错。
预期逻辑说明
代码目标是通过setTimeout实现每3秒切换一次灯泡亮灭状态,对应流程:
- 初始化全局状态
state = true,标记初始灯泡状态 - 每3秒判断一次state值:为true则打印点亮日志、把state改为false;为false则打印熄灭日志、把state改为true
- 永久循环执行上述切换逻辑
修复后的正确实现
只需要删掉setTimeout外部多余的同步递归调用,修正API拼写即可。异步回调内的递归不会造成栈溢出——因为回调会等3秒后才会执行,每次start()执行完、注册完延迟任务就会出栈,不会在调用栈中堆积:
let state = true function start() { // 修正setTimeout拼写错误 setTimeout(() => { if (state) { console.log("switch bulb on"); state = false } else { console.log("switch bulb off"); state = true } // 延迟任务执行完成后再注册下一次任务,实现循环 start() }, 3000); } // 初始仅调用一次即可启动循环 start()
运行效果
修复后的代码不会出现栈溢出问题,运行后会每间隔3秒交替打印灯泡亮/灭日志,可直接对接CSS灯泡样式的切换逻辑,实现预期的闪烁效果。
内容的提问来源于stack exchange,提问作者Namkat Cedrick
相关产品推荐
相关产品推荐

