首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >做定时任务,一定要用这个神库!!

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

作者头像
Immerse
发布2025-03-27 14:22:13
发布2025-03-27 14:22:13
13800
代码可运行
举报
文章被收录于专栏:沉浸式趣谈沉浸式趣谈
运行总次数:0
代码可运行
  • • Hey, 我是 沉浸式趣谈
  • • 本文首发于【沉浸式趣谈】,我的个人博客 https://yaolifeng.com 也同步更新。
  • • 转载请在文章开头注明出处和版权信息。
  • • 如果本文对您有所帮助,请 点赞评论转发,支持一下,谢谢!

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

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

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

cron 包:不只是个定时器

安装超级简单:

代码语言:javascript
代码运行次数:0
运行
复制
npm install cron

基础用法也很直观:

代码语言:javascript
代码运行次数:0
运行
复制
import { CronJob } from"cron";

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

看起来挺简单的,对吧?

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

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

刚开始接触 cron 表达式时,我觉得这简直像某种加密代码。* * * * * * 这六个星号到底代表什么?

在 npm 的 cron 包中,表达式有六个位置(比传统的 cron 多一个),分别是:

代码语言:javascript
代码运行次数:0
运行
复制
秒 分 时 日 月 周

比如 0 0 9 * * 1 表示每周一早上 9 点整执行。

我找到一个特别好用的网站 crontab.guru 来验证表达式。

不过注意,那个网站是 5 位的表达式,少了 "秒 "这个位置,所以用的时候需要自己在前面加上秒的设置。

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

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

前端开发中的实用场景

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

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

代码语言:javascript
代码运行次数:0
运行
复制
// 每小时刷新一次产品数据缓存
const cacheRefreshJob = newCronJob(
"0 0 * * * *",
asyncfunction () {
    try {
      const newData = awaitfetchProductData();
      updateProductCache(newData);
      console.log("产品数据缓存已更新 ");
    } catch (error) {
      console.error("刷新缓存失败:", error);
    }
  },
null,
true,
"Asia/Shanghai",
);

2. Electron 应用中的定时任务

代码语言:javascript
代码运行次数:0
运行
复制
// 在 Electron 应用中每 5 分钟同步一次本地数据到云端
const syncJob = newCronJob(
"0 */5 * * * *",
asyncfunction () {
    if (navigator.onLine) {
      // 检查网络连接
      try {
        awaitsyncDataToCloud();
        sendNotification("数据已同步 ");
      } catch (err) {
        console.error("同步失败:", err);
      }
    }
  },
null,
true,
);

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

代码语言:javascript
代码运行次数:0
运行
复制
// 每分钟检查一次用户活动状态,30 分钟无活动自动登出
const sessionCheckJob = newCronJob(
"0 * * * * *",
function () {
    const lastActivity = getLastUserActivity();
    const now = newDate().getTime();

    if (now - lastActivity > 30 * 60 * 1000) {
      console.log("用户 30 分钟无活动,执行自动登出 ");
      logoutUser();
    }
  },
null,
true,
);

踩过的那些坑

使用 cron 包时我踩过几个坑,分享给大家:

  1. 1. ** 时区问题 **:有次我设置了一个定时提醒功能,但总是提前 8 小时触发。一查才发现是因为没设置时区。所以国内用户一定要设置 'Asia/Shanghai'
代码语言:javascript
代码运行次数:0
运行
复制
// 这样才会在中国时区的下午 6 点执行
const job = new CronJob(
  "0 0 18 * * *",
  myFunction,
  null,
  true,
  "Asia/Shanghai",
);
  1. 2. **this 指向问题 **:如果你用箭头函数作为回调,会发现无法访问 CronJob 实例的 this。
代码语言:javascript
代码运行次数:0
运行
复制
// 错误示范
const job = newCronJob("* * * * * *", () => {
console.log("执行任务 ");
this.stop(); // 这里的 this 不是 job 实例,会报错!
});

// 正确做法
const job = newCronJob("* * * * * *", function () {
console.log("执行任务 ");
this.stop(); // 这样才能正确访问 job 实例
});
  1. 3. **v3 版本变化 **:如果你从 v2 升级到 v3,要注意月份索引从 0-11 变成了 1-12。

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

这是我在一个电商前端项目中实现的一个功能,用 cron 来管理各种用户通知:

代码语言:javascript
代码运行次数:0
运行
复制
import { CronJob } from"cron";
import { getUser, getUserPreferences } from"./api/user";
import { sendNotification } from"./utils/notification";

classNotificationManager {
constructor() {
    this.jobs = [];
    this.initialize();
  }

initialize() {
    // 新品上架提醒 - 每天早上 9 点
    this.jobs.push(
      newCronJob(
        "0 0 9 * * *",
        async () => {
          if (!this.shouldSendNotification("newProducts")) return;

          const newProducts = awaitthis.fetchNewProducts();
          if (newProducts.length > 0) {
            sendNotification(
              "新品上架 ",
              `今天有 ${newProducts.length}款新品上架啦!`,
            );
          }
        },
        null,
        true,
        "Asia/Shanghai",
      ),
    );

    // 限时优惠提醒 - 每天中午 12 点和晚上 8 点
    this.jobs.push(
      newCronJob(
        "0 0 12,20 * * *",
        async () => {
          if (!this.shouldSendNotification("promotions")) return;

          const promotions = awaitthis.fetchActivePromotions();
          if (promotions.length > 0) {
            sendNotification("限时优惠 ", "有新的限时优惠活动,点击查看详情!");
          }
        },
        null,
        true,
        "Asia/Shanghai",
      ),
    );

    // 购物车提醒 - 每周五下午 5 点提醒周末特价
    this.jobs.push(
      newCronJob(
        "0 0 17 * * 5",
        async () => {
          if (!this.shouldSendNotification("cartReminder")) return;

          const cartItems = awaitthis.fetchUserCart();
          if (cartItems.length > 0) {
            sendNotification(
              "周末将至 ",
              "别忘了查看购物车中的商品,周末特价即将开始!",
            );
          }
        },
        null,
        true,
        "Asia/Shanghai",
      ),
    );

    console.log("通知系统已初始化 ");
  }

asyncshouldSendNotification(type) {
    const user = getUser();
    if (!user) returnfalse;

    const preferences = awaitgetUserPreferences();
    return preferences?.[type] === true;
  }

// 其他方法 ...

stopAll() {
    this.jobs.forEach((job) => job.stop());
    console.log("所有通知任务已停止 ");
  }
}

exportconst notificationManager = newNotificationManager();

写在最后

作为前端开发者,我们的工作不只是构建漂亮的界面,还需要处理各种复杂的交互和时序逻辑。

npm 的 cron 包为我们提供了一种专业而灵活的方式来处理定时任务,特别是在 Node.js 环境下运行的前端应用(如 SSR 框架、Electron 应用等)。

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-03-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 非同质前端札记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • cron 包:不只是个定时器
  • 理解 cron 表达式,这个 "魔法公式 "
  • 前端开发中的实用场景
    • 1. 在 Next.js/Nuxt.js 等同构应用中刷新数据缓存
    • 2. Electron 应用中的定时任务
    • 3. 定时检查用户会话状态
  • 踩过的那些坑
  • 实战案例:构建一个智能通知系统
  • 写在最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档