Node.js Telegram机器人重复日志与性能优化问题排查
问题解答
1. 代码中是否存在递归?
这段代码没有递归。递归的核心是函数直接调用自身,会导致调用栈持续堆积;而你的代码是通过setTimeout将foo_interval_action加入事件队列,当前函数执行完毕后才会触发下一次调用,不会产生调用栈溢出或堆积问题。
你遇到的重复console.log输出,更可能是代码存在语法错误或多次触发了foo_interval_action执行:
- 代码末尾的
next(); });是多余的,});会引发语法错误,可能导致代码执行逻辑异常,比如意外多次启动任务; - 如果
pauseBot变量状态被意外修改为true后又变回false,或者有其他地方调用了foo_interval_action,会导致多个独立的任务队列同时运行,进而重复输出日志。
2. 性能优化建议
针对低配家用电脑长期运行的需求,可从以下几点优化:
修复语法错误
删除代码末尾多余的});,确保代码执行逻辑正常,避免意外触发多次任务。
复用时区时间实例
每次调用timezoneRecifeFormated和timezoneRecifeHour都会重新创建moment-timezone实例,这会增加不必要的性能开销。可以在foo_interval_action内只创建一次时区时间实例,复用它获取小时和格式化时间:
function foo_interval_action() { if (pauseBot == false) { const recifeTime = momentTimeZone.tz("America/Recife"); // 只创建一次实例 const currentHour = recifeTime.hour(); const formattedTime = recifeTime.format('HH:mm'); let RedOrGreen = Math.random(); let onlinePeriod = currentHour > 7 || currentHour < 3; let offlinePeriod = !onlinePeriod; // 直接推导,避免重复计算 console.log('red or green math random = ' + RedOrGreen); console.log('ONLINE period = ' + onlinePeriod); console.log('OFFLINE period = ' + offlinePeriod); if (RedOrGreen < 0.7 && onlinePeriod) { setTimeout(foo_interval_action, getRandomInterval(minimumRangeMinute, maxRangeMinute)); console.log('GREEN aposte agora!' + formattedTime); } else if (RedOrGreen >= 0.7 && onlinePeriod) { setTimeout(foo_interval_action, getRandomInterval(minimumRangeMinute, maxRangeMinute)); console.log('RED CUIDADO!' + formattedTime); } else { setTimeout(foo_interval_action, getRandomInterval(minimumRangeMinute, maxRangeMinute)); console.log('Bot offline, fora do periodo de trabalho. Agora são ' + formattedTime); } } }
确保单一任务实例运行
添加一个变量保存当前的setTimeout ID,每次触发新任务前清除之前的(如果存在),避免多个任务同时执行:
let timeoutId = null; function foo_interval_action() { if (pauseBot == false) { const recifeTime = momentTimeZone.tz("America/Recife"); const currentHour = recifeTime.hour(); const formattedTime = recifeTime.format('HH:mm'); let RedOrGreen = Math.random(); let onlinePeriod = currentHour > 7 || currentHour < 3; let offlinePeriod = !onlinePeriod; console.log('red or green math random = ' + RedOrGreen); console.log('ONLINE period = ' + onlinePeriod); console.log('OFFLINE period = ' + offlinePeriod); // 清除之前的timeout,确保只有一个任务在队列 if (timeoutId) clearTimeout(timeoutId); timeoutId = setTimeout(foo_interval_action, getRandomInterval(minimumRangeMinute, maxRangeMinute)); // 后续日志输出逻辑... if (RedOrGreen < 0.7 && onlinePeriod) { console.log('GREEN aposte agora!' + formattedTime); } else if (RedOrGreen >= 0.7 && onlinePeriod) { console.log('RED CUIDADO!' + formattedTime); } else { console.log('Bot offline, fora do periodo de trabalho. Agora são ' + formattedTime); } } else { // 暂停时清除timeout,避免后续意外触发 if (timeoutId) { clearTimeout(timeoutId); timeoutId = null; } } } // 初始启动 timeoutId = setTimeout(foo_interval_action, getRandomInterval(minimumRangeMinute, maxRangeMinute));
优化日志输出
如果日志仅用于调试,长期运行时可以减少输出频率,或者将日志写入文件而非控制台(控制台输出相对耗时)。
内容的提问来源于stack exchange,提问作者netryx
相关产品推荐
相关产品推荐

