首页 / Bun 入门教程 / 实用 API

Bun 入门教程

实用 API

本教程共 34 篇 · 第 30 篇 · 更新于 2026-08-06

BunBun.cronBun.passwordBun.hashBun.CryptoHasherBun.gc工具函数

本节目标:

  • Bun.cron 解析 cron 表达式、在进程内定时执行回调,或注册 OS 级定时任务。
  • Bun.password 完成密码的 argon2id/bcrypt 哈希与校验。
  • 区分 Bun.hash(非加密、快)与 Bun.CryptoHasher(加密哈希、可增量)。
  • Bun.gc / Bun.generateHeapSnapshot 在性能调优时主动回收与抓取堆快照。
  • 认识 Bun.sleepBun.whichBun.envBun.main 等日常小工具。

这一章把 Bun 运行时里「不好归类但很常用」的工具 API 集中讲一遍。它们大多是同步或 Promise 化的小函数,能省掉引入额外 npm 包的麻烦。

30.1 Bun.cron:定时任务

Bun 内建了 cron 支持,提供三种能力:①解析表达式求下一次触发时间;②在当前进程内按调度执行回调;③注册 OS 级别的定时任务(重启后依然生效)。

// 1)进程内定时回调
Bun.cron("0 * * * *", async () => {
  await cleanupTempFiles();
});

// 2)解析表达式,得到下一次触发的 Date
const next = Bun.cron.parse("30 9 * * MON-FRI");

// 3)注册 OS 级定时任务(脚本 + 表达式 + 任务名)
await Bun.cron("./worker.ts", "30 2 * * MON", "weekly-report");
Note

版本落点要分清:OS 级注册与表达式解析在 v1.3.11 引入(2026-03-18 发布),进程内回调调度器在 v1.3.12 补齐(2026-04-09 发布)。到本教程基线版本 v1.3.14,两者都已可用。若你的环境停在 v1.3.11,Bun.cron(expr, fn) 这种写法还不存在。

表达式语法

标准 5 字段:分 时 日 月 周。字段支持 *,(列表)、-(区间)、/(步长),月与星期可用英文缩写(JANDECMONSUN,大小写不敏感,也接受全称),星期里 07 都表示周日。还支持预定义昵称:@yearly@monthly@weekly@daily@hourly

Bun.cron.parse("*/15 * * * *");   // 下一个一刻钟整
Bun.cron.parse("@daily");         // 下一次午夜

Bun.cron.parse(expr, from?) 的第二个参数是搜索起点,省略则从当前时刻算起。返回最接近的 Date;如果约 4 年内都找不到匹配(例如写了 2 月 30 日这种永不成立的组合),返回 null

还有一个 POSIX 兼容的细节值得记:当「日」和「周」两个字段同时被限定时,采用的是「或」逻辑——任一条件满足就触发,而不是两个都要满足。这一点经常被误解,写 0 0 13 * FRI 时以为只在「13 号且周五」跑,实际是「每月 13 号」加上「每个周五」都跑。

Note

OS 级任务在不同平台落到不同后端:Linux 写 crontab、macOS 用 launchd、Windows 用任务计划程序(schtasks)。日志位置也随之不同,Linux 查 journalctl,Windows 查事件查看器。

进程内回调 vs OS 级任务

两者语义不同,按需选择:

  • 进程内回调Bun.cron(expr, fn)):随当前进程生命周期存在,进程退出任务即停;适合应用内周期任务,如清理缓存、轮询。它有几条明确保证:上一次回调结算完才排下一次(不会重叠执行)、按 UTC 调度、--hot 重载前会先清理已注册任务、支持 using 自动释放。不希望它拖住进程退出,就调用 job.unref()
  • OS 级任务Bun.cron(script, expr, name)):由系统调度器接管,机器重启后仍会运行;适合运维型定时脚本。用同一个任务名重复注册会原地覆盖旧任务,不再需要时用 await Bun.cron.remove("weekly-report") 卸载。

OS 级任务被触发时,Bun 会导入那个脚本并调用它默认导出的 scheduled() 方法,接口沿用了 Cloudflare Workers 的 Cron Triggers 约定:

// worker.ts
export default {
  async scheduled(controller) {
    // controller.cron 是触发它的那条表达式
    // controller.scheduledTime 是计划触发的时间戳
    await doWork();
  },
};

所以「写个脚本 + 注册一次」就够了,不需要再额外常驻一个进程去等时间。

连续推算多次触发时间

parse() 可链式调用,把上一次结果当起点,得到接下来若干次触发时刻:

let cursor: Date | number = Date.now();
for (let i = 0; i < 3; i++) {
  cursor = Bun.cron.parse("0 * * * *", cursor)!;
  console.log(cursor.toISOString()); // 接下来三个整点
}

这在做「任务预览」类功能时很实用:用户填一条 cron 表达式,你当场把接下来五次执行时间列给他看,比让他自己解读表达式友好得多。

30.2 Bun.password:密码哈希与校验

Bun.password 专门处理密码这种「需要抗碰撞、抗暴力」的场景,默认算法是 argon2id,也支持 bcrypt

const password = "super-secure-pa$$word";

const hash = await Bun.password.hash(password);
// $argon2id$v=19$m=65536,t=2,p=1$<salt>$<hash>

const isMatch = await Bun.password.verify(password, hash); // true

第二个参数可以选算法与调参:

const argon = await Bun.password.hash(password, {
  algorithm: "argon2id", // "argon2id" | "argon2i" | "argon2d"
  memoryCost: 8,         // 内存成本(KiB,最小 8)
  timeCost: 3,           // 迭代次数
});

const bcrypt = await Bun.password.hash(password, {
  algorithm: "bcrypt",
  cost: 4,               // 4–31
});

算法信息直接编码进哈希字符串里:bcrypt 用 Modular Crypt Format(MCF),argon2 用 PHC 格式。verify 会自动识别编码方式并选用对应校验逻辑。此外还有同步版本 Bun.password.hashSync / verifySync(计算量大,会阻塞线程,谨慎使用)。

这里有个新手常问的问题:盐值存哪儿? 答案是不用你操心。Bun.password.hash() 每次都会生成随机盐并写进返回的那串字符里,所以同一个密码两次哈希的结果一定不同。数据库里只存这一个字段就够了,不需要额外的 salt 列。

另一个容易搞错的是参数顺序:verify(明文, 哈希),别写反。写反了永远返回 false,还很难排查。

Tip

示例里的 memoryCost: 8cost: 4 是为了让演示跑得快,不要照抄到生产。这两个参数越大越抗暴力破解,同时也越慢。合理做法是在目标机器上实测,把单次哈希耗时调到 100 毫秒上下。

Warning

不要拿 Bun.hash(见下节)去哈希密码——它是非加密哈希,专为速度设计,不适合存储口令。密码场景一律用 Bun.password

30.3 Bun.hashBun.CryptoHasher:普通哈希

Bun.hash(非加密)

Bun.hash 用于哈希表、去重、校验和等追求速度的场合,默认用 Wyhash 生成 64 位哈希,返回 bigint

Bun.hash("some data here");          // 11562320457524636935n
Bun.hash(new Uint8Array([1,2,3,4])); // 也支持 TypedArray / DataView / ArrayBuffer
Bun.hash("data", 1234);              // 第二参数是可选 seed(64 位请用 BigInt)

还有一批命名算法可用(32 位返回 number,64 位返回 bigint):Bun.hash.crc32adler32cityHash32/64xxHash32/64xxHash3murmur32v3/32v2/64v2rapidhashwyhash 等。

Bun.CryptoHasher(加密哈希,可增量)

需要 sha256/sha512/md5 等加密哈希、且数据要分块喂入时,用 Bun.CryptoHasher

const hasher = new Bun.CryptoHasher("sha256");
hasher.update("hello world");
hasher.update(new Uint8Array([1, 2, 3]));
hasher.digest(); // Uint8Array(32)

支持的算法包括 blake2b256/512blake2s256sha1/224/256/384/512sha512-224/256sha3-224/256/384/512shake128/256ripemd160md5md4 等。传 key 还能算 HMAC:new Bun.CryptoHasher("sha256", "secret-key")

Tip

需要 Node 兼容接口时,node:cryptocreateHash / createHmac 在 Bun 下也可用;Bun.CryptoHasher 是 Bun 原生、更贴近增量的写法。

30.4 Bun.gcBun.generateHeapSnapshot:内存排查

JS 是垃圾回收语言,对象通常不是立即释放。做性能调优或排查内存泄漏时,可手动触发 GC 或抓取堆快照。

Bun.gc(true);  // 同步执行一次垃圾回收
Bun.gc(false); // 异步执行

抓堆快照(可用 Safari / WebKit GTK 开发者工具打开分析):

import { generateHeapSnapshot } from "bun";

const snapshot = generateHeapSnapshot();
await Bun.write("heap.json", JSON.stringify(snapshot, null, 2));
Note

这两个 API 主要服务于调试与基准测试(见第 33 章),常规业务代码无需调用 Bun.gcBun.generateHeapSnapshot 来自内置的 bun 模块。

30.5 日常小工具

API作用
Bun.sleep(ms) / Bun.sleepSync(ms)等待若干毫秒(后者阻塞线程);也可传 Date 等待到指定时刻
Bun.which(bin, opts?)类似终端 which,按 PATH 查找可执行文件路径,替代 which
Bun.envprocess.env 的别名
Bun.main当前程序入口文件的绝对路径,用于判断脚本是被直接运行还是被导入
Bun.version / Bun.revision当前 bun CLI 的版本号 / 编译所用的 git commit
Bun.randomUUIDv7()生成 UUID v7(按时间排序)

判断脚本是否「被直接运行」的常见写法:

if (import.meta.path === Bun.main) {
  // 直接 `bun run` 执行的入口逻辑
} else {
  // 被别的模块 import
}

几个小工具的实际用法:

console.log(Bun.version);                 // "1.3.14"
await Bun.sleep(1000);                    // 等 1 秒
await Bun.sleep(new Date(Date.now() + 5000)); // 等到 5 秒后的时刻

const ls = Bun.which("ls");               // "/usr/bin/ls"(按 PATH 查找)
const custom = Bun.which("node", { PATH: "/opt/bin:/usr/bin" });

const id = Bun.randomUUIDv7();            // 时间有序的 UUID v7

Bun.which 本质上是跨平台版的系统 which,能少装一个 which npm 包;Bun.sleep 既能收毫秒也能收 Date,比手写 setTimeout 包裹的 Promise 更直观。

30.6 小结

  • Bun.cron:解析表达式 + 进程内回调 + OS 级任务,三合一。
  • Bun.password:密码专用,默认 argon2id,自动识别编码、自带盐值。
  • Bun.hash:非加密、快;Bun.CryptoHasher:加密、可增量。密码别用前者。
  • Bun.gc / Bun.generateHeapSnapshot:调试与性能调优专用。
  • Bun.sleep / Bun.which / Bun.main 等小工具,能少装几个 npm 包就少装。
Tip

这些 API 都属于「运行时内置」,无需任何依赖。用到哪个就直接 import 或访问全局 Bun 命名空间即可;想看完整清单可回顾第 31 章所涉及的生态与官方 API 总览。

30.7 与 Node.js 兼容层的对应

为了方便迁移现有代码,Bun 也兼容一部分 Node.js 的同名 API,可作为备选:

  • 加密哈希:node:cryptocreateHash / createHmac 在 Bun 下可用,等价于 Bun.CryptoHasher 的用途。
  • 密码学随机:node:cryptorandomUUID / randomBytes 同样可用,Bun 额外提供了按时间排序的 Bun.randomUUIDv7()
  • 子进程:node:child_processspawn / execFile 在 Bun 下能跑,但 Bun.spawn 的流模型和 Bun.$ 的 Shell 语法通常更顺手。
Note

兼容性不是「照搬 Node」——Bun 在大多数场景行为一致,但个别边缘行为可能有差异。生产迁移前建议对关键路径补测试(参见第 21–25 章的测试章节)。