Node.js 如何组合puppeteer定时刷新与JSON变更监听逻辑
原有代码方案的不可行原因
require读取JSON的机制存在硬伤:Node的require有模块缓存特性,第一次加载sole.json后,后续哪怕手动修改了文件内容,再次调用require('./sole.json')拿到的依然是缓存中的旧值,根本检测不到startstop字段的变更,完全达不到手动改字段终止任务的需求。- 死循环写法直接阻塞事件循环:同步写的
while循环会占满JS主线程,把Node的所有异步能力(定时器、puppeteer的页面操作)全部堵死,根本跑不起来;而且循环体内写的await page.reload()在同步while块内属于语法错误,代码无法正常执行。 - 逻辑拆分完全错位:既没有实现“每隔几秒检查JSON变更”的高频检测逻辑,也没把“每2分钟刷新页面”做成独立的定时任务,两个核心需求全揉进了无效的死循环里。
正确的组合实现思路
两个核心需求本质是两个独立的定时逻辑,完全可以通过非阻塞的定时器组合实现,不需要写死循环:
- 替换JSON读取方式:彻底放弃用
require读配置,改用fs.readFileSync每次检查时直接从磁盘读取最新的文件内容,JSON.parse解析后拿到startstop字段的值,完全绕开模块缓存的影响。 - 拆分明细定时器:
- 高频检测定时器:设置1-3秒的轮询间隔,每次触发时读取最新的JSON状态,一旦检测到字段值为1,就把两个定时器全部清除,终止全流程。这种非阻塞的轮询不会卡主线程,完全满足“尽可能高频检查变更”的要求。
- 页面刷新定时器:设置2分钟的固定间隔,每次触发前先判断当前任务是否还在运行状态,只有状态正常时才执行
page.reload()操作,避免任务终止后还触发无意义的页面刷新。
- 所有异步操作(比如puppeteer的页面跳转、刷新)都要做好异常捕获,避免单次操作失败导致整个流程崩掉。
可直接参考的实现代码
const fs = require('fs'); const puppeteer = require('puppeteer'); let jsonCheckTimer = null; let pageReloadTimer = null; let taskActive = true; /** * 实时读取JSON文件状态,无模块缓存 */ function getCurrentJsonStatus() { try { const rawContent = fs.readFileSync('./sole.json', 'utf8'); const parsedData = JSON.parse(rawContent); return parsedData.startstop; } catch (err) { // 读文件失败、JSON格式错误时默认保持运行状态,避免误终止 return 0; } } async function startTask() { const browser = await puppeteer.launch(); const page = await browser.newPage(); // 替换为你要操作的目标页面地址 await page.goto('https://your-target-page.com'); // 每2秒检查一次JSON终止信号 jsonCheckTimer = setInterval(() => { const status = getCurrentJsonStatus(); if (status === 1) { taskActive = false; clearInterval(jsonCheckTimer); clearInterval(pageReloadTimer); console.log('已检测到终止信号,停止所有任务'); } }, 2000); // 每2分钟刷新一次页面 pageReloadTimer = setInterval(async () => { if (!taskActive) return; try { await page.reload({ waitUntil: 'networkidle2' }); console.log('完成一次页面刷新'); } catch (err) { console.log('页面刷新执行失败:', err); } }, 2 * 60 * 1000); } startTask();
内容的提问来源于stack exchange,提问作者user15497175
相关产品推荐
相关产品推荐

