当前位置: 首页 > news >正文

meteor-collection-hooks触发条件清单:find/findOne钩子在Meteor 3中的完整方法对照

meteor-collection-hooks触发条件清单:find/findOne钩子在Meteor 3中的完整方法对照

【免费下载链接】meteor-collection-hooksMeteor Collection Hooks项目地址: https://gitcode.com/gh_mirrors/me/meteor-collection-hooks

meteor-collection-hooks 是 Meteor 社区最常用的集合扩展包,为Mongo.Collection提供before/after钩子。但升级到Meteor 3后,findfindOne钩子的触发条件发生了根本性变化:同步方法不再触发、before.find禁止异步、钩子只在异步方法上生效。这份触发条件清单整理了 find/findOne 钩子在 Meteor 3 中的完整方法对照,帮你快速避开"钩子不执行"的坑。

一、先理解 Meteor 3 发生了什么变化

Meteor 3 全面转向异步 API(insertAsyncupdateAsync等),但find()出于兼容性仍是同步方法——它必须立刻返回 cursor 实例。这直接导致了两个结果:

  • before.find钩子必须同步执行,否则find()无法同步返回 cursor;
  • find 系列钩子只能挂在 cursor 的异步方法fetchAsync等)上触发。

这套逻辑封装在 find.js 中:同步的 before 钩子在 cursor 创建时立即执行,after 钩子则在ASYNC_METHODScountAsyncfetchAsyncforEachAsyncmapAsync)被调用后触发。

二、find 钩子触发条件完整清单

✅ 会触发 find 钩子的方法

写法before.findafter.find
collection.find({}).fetchAsync()✅ 立即触发✅ 触发
collection.find({}).countAsync()✅ 立即触发✅ 触发
collection.find({}).forEachAsync()✅ 立即触发✅ 触发
collection.find({}).mapAsync()✅ 立即触发✅ 触发

❌ 不会触发 find 钩子的方法

写法before.findafter.find
collection.find({}).fetch()❌ 不触发❌ 不触发
collection.find({}).count()❌ 不触发❌ 不触发
collection.find({}).forEach()❌ 不触发❌ 不触发
collection.find({}).map()❌ 不触发❌ 不触发

注意before.find只支持同步函数,写成async function会直接抛错Cannot use async function as before.find hook;而after.find同步、异步都支持。

三、findOne 钩子触发条件完整清单

findOne 钩子的规则更简单:只在findOneAsync()上触发,同步的findOne()一律不触发。测试用例 findone.test.js 中明确验证了这一点。

写法before.findOneafter.findOne
await collection.findOneAsync({})✅ 触发✅ 触发
collection.findOne({})❌ 不触发❌ 不触发

与 find 不同,before.findOneafter.findOne支持异步函数,且before.findOne返回false可以中止本次查询(见 findone.js)。它还用Tracker.withComputation保留了 Meteor 3 下的响应式能力,Tracker.autorun内调用findOneAsync依然能自动重跑。

四、find / findOne 钩子完整方法对照表

下面这张速查表总结了两个钩子的全部差异:

对比项before.findafter.findbefore.findOneafter.findOne
支持异步❌ 必须同步✅ 均可✅ 均可✅ 均可
触发时机cursor 创建时cursor 异步方法调用后findOneAsync调用时findOneAsync返回后
回调参数(userId, selector, options)(userId, selector, options, cursor)(userId, selector, options)(userId, selector, options, doc)
返回 false 中止
注册方式collection.before.find(fn)collection.after.find(fn)collection.before.findOne(fn)collection.after.findOne(fn)

所有注册方法都会返回一个钩子控制器,支持.replace(fn)替换和.remove()移除,方便在发布/订阅中动态管理。

五、钩子参数详解

四个钩子共享前三个参数,语义完全一致:

  • userId:当前操作用户 ID(客户端可通过模拟Meteor.userId注入,见 find_userid.test.js);
  • selector:查询条件对象,可在 before 钩子中直接修改实现软删除等逻辑;
  • options:查询选项,如{ sort, limit, fields }

唯一区别在第四个参数:after.find拿到的是cursor 实例after.findOne拿到的是查询结果文档 doc

六、实用场景:用 before.find 实现软删除过滤

借助 selector 可修改的特性,最经典的用法是软删除全局过滤:

import { Mongo } from 'meteor/mongo' const Posts = new Mongo.Collection('posts') // 全局过滤已删除文档(必须同步函数) Posts.before.find((userId, selector, options) => { selector.deletedAt = { $exists: false } }) Posts.before.findOne((userId, selector, options) => { selector.deletedAt = { $exists: false } }) // 之后所有查询都自动带上软删除条件 const posts = await Posts.find({ author: 'alice' }).fetchAsync()

注意:注册在全局集合上的before.find会影响所有查询,包括钩子内部触发的查询,这也是 find_after_hooks.test.js 中专门验证的边界场景。可用options传标记参数来区分业务查询与内部查询。

七、绕过钩子:direct 系列方法

如果某个场景需要跳过钩子,可以用direct前缀:

Posts.direct.find({}).fetchAsync() // 绕过 find 钩子 Posts.direct.findOne({}) // 绕过 findOne 钩子

底层实现位于 collection-hooks.js,通过directEnv环境变量标记当前调用,配合directOp/hookedOp实现钩子的启用与旁路。

八、版本兼容性与升级提醒

本包版本v2.1.0,兼容Meteor 2.16+ 到 3.1+。但请注意 v2.0.0 起的破坏性变更:

  1. before.find禁用异步函数(v2 之前允许);
  2. find/findOne 钩子只响应异步方法(findOneAsyncfetchAsync等);
  3. 同步调用(findOne()fetch())不再触发任何钩子。

如果你的旧代码依赖同步方法触发钩子,升级后务必逐条核对 History.md 中的变更记录。官方文档与完整用法见 README.md,类型定义可参考 collection-hooks.d.ts。

结语:三句话记住触发规则

  • find 钩子:before 同步执行、after 跟 async 方法走;
  • findOne 钩子:只认findOneAsync
  • 同步方法findOne/fetch/count):一律不触发。

收藏这份 meteor-collection-hooks 触发条件清单,升级 Meteor 3 时对照排查,钩子失灵的问题就能一次解决。

【免费下载链接】meteor-collection-hooksMeteor Collection Hooks项目地址: https://gitcode.com/gh_mirrors/me/meteor-collection-hooks

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

http://www.cnnetsun.cn/news/4103522.html

相关文章:

  • 文件解包工具终极指南:一款万能解压工具搞定500+格式
  • 遗嘱继承律所联系方式推荐 提供遗嘱订立继承服务 2026年官方咨询渠道及办理流程介绍
  • GNOME 桌面防休眠完整指南:Caffeine 扩展安装与自动化设置
  • 抖音视频怎么保存到本地?免费无水印批量下载工具,新手 10 分钟就能搞定
  • 性能分析怎样控制采样开销
  • KMS_VL_ALL_AIO 激活脚本全攻略:一个文件如何把 Windows 和 Office 的授权打理得明明白白
  • 终极指南:用 Notepad-- 十六进制编辑破解 5 类二进制文件难题
  • Mac运行Windows软件不再折腾:Whisky免费开源方案从装到跑全记录
  • 个人微信API调用失败:登录掉线与回调排查
  • macOS 菜单栏终极救星:免费开源 Ice 三步搞定图标收纳,刘海不再挡图标
  • mapreduce的工作原理
  • 归一化与标准化
  • Depressurizer 完整上手指南:一次配置,让 Steam 数百款游戏自动分类
  • OBS背景移除插件极速上手:10分钟告别绿幕,AI抠像开启无背景直播
  • 基于Spring Boot的教学资源共享网站的设计与实现源码+文档
  • 别再让窗口打架了!Loop窗口透明度,4个玩法让两层内容同屏显示
  • 实测 IOPaint:免费开源还能一键去水印的 AI 图片修复工具,到底有多香
  • 基于SpringBoot的教学管理信息系统(源码+lw+部署文档+讲解等)
  • 基于微信小程序的学习交流平台系统(源码+文档+部署讲解等)
  • vscode-terosHDL 完整上手指南:一套让 HDL 开发变得清爽的现代化工具链
  • 本地离线OCR工具部署与实战:从表格识别到API集成全解析
  • Tabby 终端完整上手指南:一个窗口搞定本地 Shell、SSH 远程连接与串口调试
  • 计算机安全:构建坚不可摧的数字防线
  • 不用U盘也能给PS3装游戏:webMAN-MOD上手记
  • 让 AI 替你熬夜打牌:Poker 扑克机器人保姆级指南,一键托管三大平台德州扑克
  • AI论文工具最全盘点:语法纠错+降重降AI一篇文章讲透
  • FGO 自动刷本终极指南:用对工具,无限池和每周任务可以一晚上清空
  • 逐行解读Qwen3-VL-8B-Instruct-da8w8-torchao-v0.17.0量化配置:Int8DynamicActivationInt8WeightConfig完全指南
  • ComfyUI 高效工作流指南:KJNodes 自定义节点,让繁琐配置一次清零
  • 2026 热门采购管理系统盘点,专业选型推荐