2026 年 5 月 7 日,ClojureScript 1.12.145 发布。
最值得看的一行变化是:函数前加 ^:async,编译器可以直接生成 JavaScript 原生 async function。函数体和测试里也可以用 await。
这不是 ClojureScript 发明了 async/await。JavaScript 早就有了。ClojureScript 这次做的,是在已经转向 ECMAScript 2016 作为目标后,把自己和现代 JS 生态之间一块很硌脚的石头搬开。
改动很小,但位置很准
这次更新可以压成一张卡片。
| 项目 | ClojureScript 1.12.145 的变化 | 直接影响 |
|---|---|---|
| 发布时间 | 2026-05-07 | 明确落在 1.12.145 版本 |
| 函数标注 | defn ^:async | 编译器输出原生 JS async function |
| 函数体 | 可使用 await | 更顺地处理 Promise 返回值 |
| 测试 | deftest ^:async | 异步测试可少写包装代码 |
| 编译前提 | 目标已转向 ECMAScript 2016 | 才有条件更直接面向现代 JS 输出 |
官方示例里,ClojureScript 函数用 ^:async 标注后,内部可以 await (Promise/resolve 10)。编译结果不再只是绕一层模拟控制流,而是落到 JavaScript 的原生 async function。
测试也吃到同一套能力。deftest ^:async 之后,测试代码可以等待异步结果,再断言。
这里的关键词不是“更酷”。是“少绕路”。
官方还提到,在 Clojure 调查中,async functions 是用户最期待的 ClojureScript JavaScript interop 增强项。这个信号很具体:需求不是维护者拍脑袋想出来的,而是开发者在真实项目里被 Promise、浏览器 API 和 JS 库磨出来的。
受影响最大的是现有项目和库维护者
现代前端默认讲 Promise 和 async/await。fetch、权限请求、浏览器能力、第三方库,很多接口都围着这套模型走。
ClojureScript 过去不是不能接。问题是接得不够省心。
| 场景 | 过去常见成本 | 现在可能减少的成本 |
|---|---|---|
| 调现代 Browser API | 写适配层,或引额外依赖 | 直接用 async 函数贴近 JS 调用习惯 |
| 接热门 JS 库 | ClojureScript 与 Promise 语义来回转换 | 胶水代码更少 |
| 写异步测试 | 额外包装异步流程 | deftest ^:async 更直给 |
| 新人读代码 | 在 ClojureScript 写法和 JS 异步模型之间跳转 | 语义更接近宿主生态 |
对现有 ClojureScript 团队,我会建议动作很克制:新写的浏览器 API 调用、新接入的 JS 库、异步测试,优先试 ^:async。老代码没必要为了“用上新特性”大面积翻修。
对库维护者,影响更直接。文档、示例和测试可以开始考虑补一版 async/await 写法。不是为了追潮流,而是为了让调用者少装一层适配心智。
这里也有边界。
这次更新不能自动消灭所有异步复杂度。Promise 的错误处理、调用链里的返回值约定、不同构建配置下的输出预期,仍然要靠项目自己管。官方说的是常见现代 Browser API 和热门库互操作场景可减少额外依赖,不是承诺所有异步代码从此变简单。
所以,最该观察的不是社区会不会热闹几天。
更该看三件小事:项目里能不能少掉一批包装代码;库文档会不会跟进 ^:async 示例;测试套件引入 async 后是否保持稳定清楚。
这些比口号诚实。
我的判断:别和宿主生态较劲
ClojureScript 的价值,不在于假装 JavaScript 不存在。
它的价值在于用 Clojure 的数据模型、函数式风格、宏和工具链,去写能跑在 JavaScript 世界里的程序。这里一直有张力:语言有自己的审美,宿主生态有自己的事实标准。
async/await 就是今天 JavaScript 的事实标准之一。
如果 ClojureScript 在这里继续绕,结果不会更纯粹,只会更费劲。开发者不是来参加语言美学辩论的。人要接 API,要写测试,要交付。
“天下熙熙,皆为利来。”放到技术生态里,这个“利”不是只指钱。也是时间、维护成本、招聘成本、迁移成本。谁让开发者少绕路,谁就多一分留下来的理由。
但也别把它吹成 ClojureScript 的复兴证据。
目前能确认的只是:ClojureScript 补上了一个用户明确想要、现代 JS 生态确实需要、边界相对清楚的互操作能力。它没有证明采用率上升,也不意味着 ClojureScript 放弃自身语义。
我更愿意把它看成一次健康的现实主义。
小众语言最怕的不是小。小有小的锋利。真正危险的是在日常开发处处让人多付费:多查文档,多写桥接,多修边角,多解释给新人听。
漂亮的抽象救不了糟糕的日常体验。
ClojureScript 这次选的位置不错:不把自己伪装成 JavaScript,也不跟 JavaScript 的运行现实赌气。该输出原生 async function,就输出。该让测试里直接 await,就让。
这不是没骨头。
这是知道自己站在哪片地上。
