做定时任务,一定要用这个神库!!

news/2025/3/31 12:49:37/文章来源:https://www.cnblogs.com/leadingcode/p/18797775
  • Hey, 我是 沉浸式趣谈
  • 本文首发于【沉浸式趣谈】,我的个人博客 https://yaolifeng.com 也同步更新。
  • 转载请在文章开头注明出处和版权信息。
  • 如果本文对您有所帮助,请 点赞评论转发,支持一下,谢谢!

说实话,作为前端开发者,我们经常需要处理一些定时任务,比如轮询接口、定时刷新数据、自动登出等功能。

过去我总是用 setTimeoutsetInterval,但这些方案在复杂场景下并不够灵活。

我寻找了更可靠的方案,最终发现了 cron 这个 npm 包,为我的前端项目(特别是 Node.js 环境下运行的那部分)带来了专业级的定时任务能力。

cron 包:不只是个定时器

安装超级简单:

npm install cron

基础用法也很直观:

import { CronJob } from 'cron';const job = new CronJob('0 */30 * * * *', // 每30分钟执行一次function () {console.log('刷新用户数据...');// 这里放刷新数据的代码},null, // 完成时的回调true, // 是否立即启动'Asia/Shanghai' // 时区
);

看起来挺简单的,对吧?

但这个小包却能解决前端很多定时任务的痛点。

理解 cron 表达式,这个"魔法公式"

刚开始接触 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 特别有用:

1. 在 Next.js/Nuxt.js 等同构应用中刷新数据缓存

// 每小时刷新一次产品数据缓存
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'
);

2. Electron 应用中的定时任务

// 在 Electron 应用中每5分钟同步一次本地数据到云端
const syncJob = new CronJob('0 */5 * * * *',async function () {if (navigator.onLine) {// 检查网络连接try {await syncDataToCloud();sendNotification('数据已同步');} catch (err) {console.error('同步失败:', err);}}},null,true
);

3. 定时检查用户会话状态

// 每分钟检查一次用户活动状态,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 包时我踩过几个坑,分享给大家:

  1. 时区问题:有次我设置了一个定时提醒功能,但总是提前 8 小时触发。一查才发现是因为没设置时区。所以国内用户一定要设置 'Asia/Shanghai'
// 这样才会在中国时区的下午6点执行
const job = new CronJob('0 0 18 * * *', myFunction, null, true, 'Asia/Shanghai');
  1. this 指向问题:如果你用箭头函数作为回调,会发现无法访问 CronJob 实例的 this。
// 错误示范
const job = new CronJob('* * * * * *', () => {console.log('执行任务');this.stop(); // 这里的 this 不是 job 实例,会报错!
});// 正确做法
const job = new CronJob('* * * * * *', function () {console.log('执行任务');this.stop(); // 这样才能正确访问 job 实例
});
  1. v3 版本变化:如果你从 v2 升级到 v3,要注意月份索引从 0-11 变成了 1-12。

实战案例:构建一个智能通知系统

这是我在一个电商前端项目中实现的一个功能,用 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 应用等)。

它让我们能够用简洁的表达式设定复杂的执行计划,帮助我们构建更加智能和用户友好的前端应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/907079.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

怎么办?听说Windows远程桌面要撤销?解决办法还真有!

3月11日微软正式宣布,将在2025年5月27日关闭并从Microsoft Store中移除Windows远程桌面应用程序,用户将无法通过旧版远程桌面访问这些功能。微软公司此次决定下架Microsoft远程桌面应用,主要是为了推广功能更为强大的Windows App,这种23年上线的解决方案提供了更加统一的界…

电脑文件同步软件,想要备份电脑文方法有哪些?

备份电脑文件的方法有多种,可根据需求选择适合的方案。以下是常见的备份方式及工具推荐,涵盖不同场景:一、使用系统内置工具 Windows 文件历史记录 方法: 连接外部硬盘或网络驱动器。 搜索「文件历史记录」→ 选择驱动器 → 开启自动备份。 可设置备份频率(如每小时)。 二…

我的家庭实验室服务器集群硬件清单

概述 之前有热心读者想要了解我的家庭实验室服务器集群的硬件配置清单. 所以有这篇文章.📝声明: 不是广告, 不是推广, 不是软广.先放2张照片:📝声明: 确实没有理线天赋, 这已经是我理线的极限了, 求轻喷.😂硬件包括:网络一图左下亮绿光的: 瑞莎 Radxa E20C 一图中下: 兮克…

python+pytest+loguru+allure日志封装

一、日志类封装from io import StringIO import sys import os from loguru import logger sys.path.append((os.path.abspath(os.path.join(os.path.dirname(__file__), ../)))) project_path = os.path.dirname(os.path.join(os.path.dirname(__file__))) log_path = os.path…

瑞芯微嵌入式方案概述

瑞芯微(Rockchip)是一家专注于高性能、低功耗芯片设计的中国半导体公司,其嵌入式解决方案广泛应用于智能终端、物联网、工业控制、多媒体处理等领域。以下是瑞芯微嵌入式方案的核心特点、典型应用及开发资源的总结: 一、瑞芯微嵌入式处理器系列 瑞芯微的芯片基于ARM架构,覆…

ggplot2中绘制渐变色的散点图

001、library(ggplot2)data <- data.frame(x = rnorm(100), y = rnorm(100) )ggplot(data, aes(x = x, y = y, color = y)) +geom_point(size = 3) +scale_color_gradient(low = "blue", high = "red") 。

raid级别、存储连接方式

硬盘越大,一搬转速越慢。还有看高速缓存 磁盘阵列能够容纳多少块硬盘 绝对磁盘存储柜的最大存储空间 raid提高吞吐量,保护数据 磁盘阵列柜支持哪些raid级别 raid卡上有缓存 数据先写到磁盘阵列的控制卡,再写到硬盘上 所以如果磁盘阵列卡如果断掉会导致数据丢失,一般磁盘阵列…

根据 2025 年全国青少年信息素养大赛官方通知:算法创意实践挑战赛(C++ 语言)小学组

根据 2025 年全国青少年信息素养大赛官方通知,算法创意实践挑战赛(C++ 语言)小学组的报名时间和考试时间安排如下: 报名时间 2025 年 1 月 10 日至 2025 年 4 月 22 日(具体截止时间以官方报名平台显示为准)。 考试时间初赛:2025 年 5 月(具体日期待定,需关注赛前通知…

众为兴机器人常用技巧

管理员密码 26722719 干涉空间信号设置系统信号配置

R语言中ggplot绘图去除灰色背景并保留外围框线

001、R语言中ggplot绘图去除灰色背景并保留外围框线library(ggplot2)data <- data.frame(x = rnorm(10),y = rnorm(10) )ggplot(data, aes(x = x, y = y)) +geom_point() +theme(panel.background = element_blank(), ## 去除灰色背景axis.line = element_line(colou…

机器学习优化算法

优化算法——SGD、Momentum、Adagrad、RMSprop、Adam、AdamW统一数学表达:设损失函数为$\mathcal{L}(\theta) $,学习率为$\eta$。每次迭代仅使用一个随机小批量(mini-batch)数据计算梯度。 从训练集中采样包含小批量$m$个样本${x{(1)},\cdots,x{(m)}}$,其对应的目标为${y{…

数码管静态显示

前言 目标 控制LED数码管,静态显示数字 原理 51 单片机的 LED 数码管有8个 每个数码管又由 8 个数码段组成选择要点亮的 LED 数码管的位置, 一共8个位置点亮特定 LED 数码管的数码段, 通过不同的组合,从而显示出想要的字符效果图参考资料 [4-1]静态数码管显示 位码 一共是8个…