
说实话,作为前端开发者,我们经常需要处理一些定时任务,比如轮询接口、定时刷新数据、自动登出等功能。
过去我总是用 setTimeout 和 setInterval,但这些方案在复杂场景下并不够灵活。
我寻找了更可靠的方案,最终发现了 cron 这个 npm 包,为我的前端项目(特别是 Node.js 环境下运行的那部分)带来了专业级的定时任务能力。
安装超级简单:
npm install cron 基础用法也很直观:
import { CronJob } from 'cron'; const job = new CronJob( '0 */30 * * * *', // 每 30 分钟执行一次 function () { console.log('刷新用户数据...'); // 这里放刷新数据的代码 }, null, // 完成时的回调 true, // 是否立即启动 'Asia/Shanghai' // 时区 ); 看起来挺简单的,对吧?
但这个小包却能解决前端很多定时任务的痛点。
刚开始接触 cron 表达式时,我觉得这简直像某种加密代码。* * * * * * 这六个星号到底代表什么?
在 npm 的 cron 包中,表达式有六个位置(比传统的 cron 多一个),分别是:
秒 分 时 日 月 周 比如 0 0 9 * * 1 表示每周一早上 9 点整执行。
我找到一个特别好用的网站 crontab.guru 来验证表达式。
不过注意,那个网站是 5 位的表达式,少了"秒"这个位置,所以用的时候需要自己在前面加上秒的设置。
月份和星期几还可以用名称来表示,更直观:
// 每周一、三、五的下午 5 点执行 const job = new CronJob('0 0 17 * * mon,wed,fri', function () { console.log('工作日提醒'); }); 作为前端开发者,我在这些场景中发现 cron 特别有用:
// 每小时刷新一次产品数据缓存 const cacheRefreshJob = new CronJob( '0 0 * * * *', async function () { try { const newData = await fetchProductData(); updateProductCache(newData); console.log('产品数据缓存已更新'); } catch (error) { console.error('刷新缓存失败:', error); } }, null, true, 'Asia/Shanghai' ); // 在 Electron 应用中每 5 分钟同步一次本地数据到云端 const syncJob = new CronJob( '0 */5 * * * *', async function () { if (navigator.onLine) { // 检查网络连接 try { await syncDataToCloud(); sendNotification('数据已同步'); } catch (err) { console.error('同步失败:', err); } } }, null, true ); // 每分钟检查一次用户活动状态,30 分钟无活动自动登出 const sessiOnCheckJob= new CronJob( '0 * * * * *', function () { const lastActivity = getLastUserActivity(); const now = new Date().getTime(); if (now - lastActivity > 30 * 60 * 1000) { console.log('用户 30 分钟无活动,执行自动登出'); logoutUser(); } }, null, true ); 使用 cron 包时我踩过几个坑,分享给大家:
'Asia/Shanghai'!// 这样才会在中国时区的下午 6 点执行 const job = new CronJob('0 0 18 * * *', myFunction, null, true, 'Asia/Shanghai'); // 错误示范 const job = new CronJob('* * * * * *', () => { console.log('执行任务'); this.stop(); // 这里的 this 不是 job 实例,会报错! }); // 正确做法 const job = new CronJob('* * * * * *', function () { console.log('执行任务'); this.stop(); // 这样才能正确访问 job 实例 }); 这是我在一个电商前端项目中实现的一个功能,用 cron 来管理各种用户通知:
import { CronJob } from 'cron'; import { getUser, getUserPreferences } from './api/user'; import { sendNotification } from './utils/notification'; class NotificationManager { constructor() { this.jobs = []; this.initialize(); } initialize() { // 新品上架提醒 - 每天早上 9 点 this.jobs.push( new CronJob( '0 0 9 * * *', async () => { if (!this.shouldSendNotification('newProducts')) return; const newProducts = await this.fetchNewProducts(); if (newProducts.length > 0) { sendNotification('新品上架', `今天有${newProducts.length}款新品上架啦!`); } }, null, true, 'Asia/Shanghai' ) ); // 限时优惠提醒 - 每天中午 12 点和晚上 8 点 this.jobs.push( new CronJob( '0 0 12,20 * * *', async () => { if (!this.shouldSendNotification('promotions')) return; const promotiOns= await this.fetchActivePromotions(); if (promotions.length > 0) { sendNotification('限时优惠', '有新的限时优惠活动,点击查看详情!'); } }, null, true, 'Asia/Shanghai' ) ); // 购物车提醒 - 每周五下午 5 点提醒周末特价 this.jobs.push( new CronJob( '0 0 17 * * 5', async () => { if (!this.shouldSendNotification('cartReminder')) return; const cartItems = await this.fetchUserCart(); if (cartItems.length > 0) { sendNotification('周末将至', '别忘了查看购物车中的商品,周末特价即将开始!'); } }, null, true, 'Asia/Shanghai' ) ); console.log('通知系统已初始化'); } async shouldSendNotification(type) { const user = getUser(); if (!user) return false; const preferences = await getUserPreferences(); return preferences?.[type] === true; } // 其他方法... stopAll() { this.jobs.forEach(job => job.stop()); console.log('所有通知任务已停止'); } } export const notificatiOnManager= new NotificationManager(); 作为前端开发者,我们的工作不只是构建漂亮的界面,还需要处理各种复杂的交互和时序逻辑。
npm 的 cron 包为我们提供了一种专业而灵活的方式来处理定时任务,特别是在 Node.js 环境下运行的前端应用(如 SSR 框架、Electron 应用等)。
它让我们能够用简洁的表达式设定复杂的执行计划,帮助我们构建更加智能和用户友好的前端应用。
1 hkingstu 264 天前 这个 cron 库看起来 hin 实用 |
2 lisxour 264 天前 我用的是这个,croner |
3 fov6363 264 天前 如果 node 服务署多个的话,可能要考虑抢占式运行,不了每个服务都运行定时任务有时候会有问题 |