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

  • Hey, 我是 沉浸式趣谈
  • 本文首发于【沉浸式趣谈】,我的个人博客 yaolifeng.com 也同步更新。
  • 转载请在文章开头注明出处和版权信息。
  • 如果本文对您有所帮助,请 点赞评论转发,支持一下,谢谢!

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

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

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

cron 包:不只是个定时器

安装超级简单:

bash 复制代码
npm install cron

基础用法也很直观:

javascript 复制代码
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 位的表达式,少了"秒"这个位置,所以用的时候需要自己在前面加上秒的设置。

月份和星期几还可以用名称来表示,更直观:

javascript 复制代码
// 每周一、三、五的下午5点执行
const job = new CronJob('0 0 17 * * mon,wed,fri', function () {
    console.log('工作日提醒');
});

前端开发中的实用场景

作为前端开发者,我在这些场景中发现 cron 特别有用:

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

javascript 复制代码
// 每小时刷新一次产品数据缓存
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 应用中的定时任务

javascript 复制代码
// 在 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. 定时检查用户会话状态

javascript 复制代码
// 每分钟检查一次用户活动状态,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'
javascript 复制代码
// 这样才会在中国时区的下午6点执行
const job = new CronJob('0 0 18 * * *', myFunction, null, true, 'Asia/Shanghai');
  1. this 指向问题:如果你用箭头函数作为回调,会发现无法访问 CronJob 实例的 this。
javascript 复制代码
// 错误示范
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 来管理各种用户通知:

javascript 复制代码
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 应用等)。

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

相关推荐
代码搬运媛4 小时前
Jest 测试框架详解与实现指南
前端
counterxing5 小时前
Agent 跑起来之后,难的是复用、观测和评测
node.js·agent·ai编程
counterxing5 小时前
我把 Codex 里的 Skills 做成了一个 MCP,还支持分享
前端·agent·ai编程
wangqiaowq5 小时前
windows下nginx的安装
linux·服务器·前端
之歆6 小时前
DAY_12JavaScript DOM 完全指南(二):实战与性能篇
开发语言·前端·javascript·ecmascript
发现一只大呆瓜6 小时前
Vite凭什么这么快?3分钟带你彻底搞懂 Vite 热更新的幕后黑手
前端·面试·vite
Maimai108086 小时前
React如何用 @microsoft/fetch-event-source 落地 SSE:比原生 EventSource 更灵活的实时推送方案
前端·javascript·react.js·microsoft·前端框架·reactjs·webassembly
kyriewen8 小时前
产品经理把PRD写成“天书”,我用AI半小时重写了一遍,他当场愣住
前端·ai编程·cursor
Patrick_Wilson8 小时前
知识沉淀的四层模型:从个人笔记到企业资产,让文档真正长出复利
面试·程序员·ai编程
humcomm8 小时前
元框架的工作原理详解
前端·前端框架