快速入门
在当前进程中按计划运行回调:Bun.cron.parse()
解析 cron 表达式并返回 UTC 时区的下一个匹配 Date。
参数
返回值
Date | null — 下一个匹配时间,如果 8 年内没有匹配则返回 null(例如,2 月 30 日)。
链式调用
重复调用parse() 以获取一系列即将到来的时间:
Cron 表达式语法
标准 5 字段格式:minute hour day-of-month month day-of-week
特殊字符
命名值
月份和星期字段接受不区分大小写的名称:0 和 7 都表示星期日。
预定义昵称
时区
Bun.cron.parse() 和进程内 Bun.cron(schedule, handler) 按 UTC 解释调度。无需处理夏令时 — 0 9 * * * 始终表示 9:00 UTC。
OS 级别的 Bun.cron(path, schedule, title) 使用系统的本地时区,因为 crontab、launchd 和 Windows Task Scheduler 就是这样工作的。要使两种形式一致,请使用 TZ=UTC 运行进程。
日期和星期的交互
当同时指定了日期(月)和星期(两者都不是*)时,表达式在任一条件为真时匹配。这遵循 POSIX cron 标准。
*)时,仅使用该字段进行匹配。
Bun.cron(schedule, handler) — 进程内
在当前进程内按 cron 计划运行回调。
参数
同步返回一个
CronJob。如果表达式无效或没有未来出现机会,则抛出 TypeError,如 "0 0 30 2 *"(2 月 30 日)。
无重叠保证
下一次触发时间仅在处理器(包括其返回的任何Promise)安顿后计算。如果您的处理器需要 90 秒,而调度是 * * * * *,那么第二次触发是在处理器完成后第一个分钟边界,而不是首次触发后 60 秒。调用永远不会堆叠。
错误处理
错误遵循setTimeout 语义:
- 同步
throw会触发process.on("uncaughtException")。 - 被 reject 的返回
Promise会触发process.on("unhandledRejection")。
1 退出。有监听器时,任务继续运行 — 它不会在第一次失败时停止。
bun --hot
在 bun --hot 下,所有进程内 cron 任务会在模块图重新评估之前立即停止。源代码中仍然存在的每个 Bun.cron() 调用会重新注册。编辑调度、编辑处理器或完全删除该行都会在保存时生效,而不会泄漏定时器。
CronJob 句柄
CronJob 是 Disposable — using job = Bun.cron(...) 在作用域退出时自动停止。stop()、ref() 和 unref() 都返回该任务以支持链式调用。
假定时器
进程内 cron 遵循jest.useFakeTimers()。setSystemTime()、advanceTimersByTime() 和 runAllTimers() 控制其触发时间,因此您可以测试计划的回调而无需等待真实时钟。
Bun.cron(path, schedule, title) — OS 级别
注册一个按计划运行 JavaScript/TypeScript 模块的 OS 级别 cron 任务。
参数
使用相同的
title 重新注册会原地覆盖现有任务 — 旧调度被替换,而不是重复。
scheduled() 处理器
注册的脚本必须导出一个默认对象,其中包含 scheduled() 方法,遵循 Cloudflare Workers Cron Triggers API:
worker.ts
async。Bun 会等待返回的 promise 安顿后才退出。
各平台的工作原理
Linux
Bun 使用 crontab 注册任务。每个任务以一行形式存储在用户的 crontab 中,上方带有# bun-cron: <title> 标记注释。
crontab 条目如下:
scheduled() 处理器。
查看已注册的任务:
scheduled() 处理器中添加日志记录。
无需代码手动卸载:
macOS
Bun 使用 launchd 注册任务。每个任务作为 plist 文件安装到:StartCalendarInterval 定义调度。支持带有范围、列表或步长的复杂模式 — Bun 会将其展开为多个 StartCalendarInterval 字典(笛卡尔积)。
查看已注册的任务:
weekly-report 的任务:
Windows
Bun 使用 Windows Task Scheduler 和基于 XML 的任务定义。每个任务注册为名为bun-cron-<title> 的计划任务,使用 CalendarTrigger 元素和 Repetition 模式。
大多数 cron 表达式得到完全支持,包括 @daily、@weekly、@monthly、@yearly、范围(1-5)、列表(1,15)、命名日期/月份和日期模式。
用户上下文
Bun 使用S4U(Service-for-User) 登录类型注册任务,即使用户未登录也会以注册用户身份运行任务 — 与 Linux crontab 行为一致。不存储密码。
TCP/IP 网络(fetch()、HTTP、WebSocket、数据库连接)正常工作。唯一的限制是 S4U 任务无法访问 Windows 认证的网络资源(SMB 文件共享、映射驱动器、Kerberos/NTLM 服务)。
在无头服务器和 CI 环境中,如果当前用户的安全标识符(SID)无法解析 — 例如由 NSSM 或类似工具创建的服务帐户 — Bun.cron() 会失败并显示说明问题的错误。解决方法是:以普通用户帐户运行 Bun,或使用 schtasks /create /xml <file> /tn <name> /ru SYSTEM /f 手动创建计划任务。
触发器限制
在所有平台上都有效的表达式:
在 Windows 上失败的表达式(但在 Linux 和 macOS 上有效):
关键因素是表达式是否可以使用
Repetition 间隔(单个触发器)还是必须展开为单独的 CalendarTrigger 元素。能整除 60 的分钟步长(*/1、*/2、*/3、*/4、*/5、*/6、*/10、*/12、*/15、*/20、*/30)使用 Repetition,无论其他字段如何都能工作。不能整除 60 的步长(*/7、*/8、*/9、*/11、*/13 等)必须展开,而在 24 小时活跃的情况下,计数很快就会超过 48。
要解决此问题,请简化表达式或限制小时范围:
Windows 容器
查看已注册的任务:bun-cron-<title> 的任务,右键单击并删除。
Bun.cron.remove()
按标题移除先前注册的 cron 任务。适用于所有平台。
Bun.cron() 所做的操作:
移除不存在的任务会无错误地 resolve。