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

避免Node.js递归调用函数时出现栈溢出问题

解决Node.js代理检查函数的栈溢出问题

我一眼就看出问题出在你的递归调用方式上——当STACK里有代理地址时,你是同步递归调用check_proxy(),这会导致调用栈不断累积,一旦STACK里的元素足够多,就会触发栈溢出错误。而STACK为空时的setTimeout是异步调用,不会有这个问题,但有元素时的同步递归才是罪魁祸首。

问题根源拆解

看这段核心代码:

await open_browser(ipport);
check_proxy(); // 这里是同步递归,直接压入当前调用栈

每次检查完一个代理,你立刻同步调用check_proxy(),新的调用会直接加到当前调用栈里,而不是回到事件循环重新启动。如果STACK里有几百上千个代理,调用栈会越来越深,最终超过Node.js的栈大小限制。

修复方案

只需要把同步递归改成异步调度,让每次check_proxy()的调用回到事件循环,避免栈累积。推荐用process.nextTick(),它会在当前事件循环的微任务队列里执行,比宏任务更快,完美符合你“完成一个检查后立即启动下一个”的需求。

修改后的完整代码:

var STACK = [] ;
async function check_proxy(){
 if(STACK.length < 1 ) {
  setTimeout(()=>check_proxy() , 2000 );
  return ;
 }
 var ipport = STACK.pop();
 console.log(`------- checking ${ipport}---------`);
 await open_browser(ipport);
 // 改成异步调度,重置调用栈
 process.nextTick(check_proxy);
}
async function open_browser(ipport){
 // do proxy checking,这里补上了你遗漏的ipport参数!
}
check_proxy();

额外注意事项

  1. 你原来的open_browser函数没有接收ipport参数,这会导致检查逻辑无法拿到目标代理地址,我在代码里补上了这个关键参数。
  2. 用process.nextTick()代替同步调用后,每次check_proxy()都会在当前异步操作完成后,从事件循环重新开始执行,调用栈会被自动重置,彻底解决栈溢出问题。
  3. STACK为空时的setTimeout逻辑可以保留,它会每隔2秒检查一次栈是否有新代理,这个异步逻辑本身不会造成栈问题。

这样修改后,既满足你“完成一个检查立即启动下一个”的需求,又彻底规避了栈溢出的风险,不用依赖setInterval,也不用盲目延长超时时间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:18:10