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

如何在Node.js中实现定时递归函数且不触发RangeError栈溢出

问题原因
  • 核心错误是setTimeout(timeDisplay() , {}, refresh)的写法不符合规范:timeDisplay()带括号会立即执行该函数,而不是将函数作为回调交给setTimeout延迟1秒触发。
  • 这一错误会导致程序进入无等待的无限递归调用链路:timeDisplay()执行完直接调用timeClock(),timeClock()又立刻执行timeDisplay(),完全没有1秒延迟,所以打印的时间都是相同的,且调用栈会快速耗尽,最终抛出RangeError: Maximum call stack size exceeded错误。
  • 你提到的前端环境能正常运行并不符合实际逻辑,大概率是你移植代码的时候出现了笔误,原生JS前端环境运行这段代码同样会触发栈溢出错误,只是浏览器的调用栈上限比Node.js略高,看起来能多运行几秒而已。
解决方案

将setTimeout的第一个参数改为函数引用即可,不需要加执行括号,同时可以删掉无用的第二个空对象参数:
把原代码中的mytime = setTimeout(timeDisplay() , {}, refresh)修改为mytime = setTimeout(timeDisplay, refresh)

修正后的完整可运行代码
function addZeroes(num) {
    if (num < 10) {
        var new_num = "0" + num  
    } else {
        var new_num = num
    }
    return new_num
}

function timeClock(){
    var refresh=1000; // 刷新间隔单位为毫秒
    mytime = setTimeout(timeDisplay, refresh)
}
function timeDisplay() {
    rightNow = new Date();
    minute = rightNow.getMinutes(); 
    hour = rightNow.getHours(); 
    seconds = rightNow.getSeconds();
    theTime = ""
    theTime += addZeroes(hour) + ":" + addZeroes(minute) + ":" + addZeroes(seconds);

    console.log(theTime)
    timeClock()
}

timeDisplay()
可选优化方案

你也可以直接用setInterval实现固定间隔执行,无需每次递归调用setTimeout,代码更简洁:

function addZeroes(num) {
    return num < 10 ? "0" + num : num
}

function printTime() {
    const rightNow = new Date()
    const theTime = `${addZeroes(rightNow.getHours())}:${addZeroes(rightNow.getMinutes())}:${addZeroes(rightNow.getSeconds())}`
    console.log(theTime)
}

// 立即打印一次当前时间,之后每1秒打印一次
printTime()
setInterval(printTime, 1000)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 16:06:08