ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

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

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-hooksmeteor-collection-hooks 是 Meteor 社区最常用的集合扩展包为Mongo.Collection提供before/after钩子。但升级到Meteor 3后find和findOne钩子的触发条件发生了根本性变化同步方法不再触发、before.find禁止异步、钩子只在异步方法上生效。这份触发条件清单整理了 find/findOne 钩子在 Meteor 3 中的完整方法对照帮你快速避开钩子不执行的坑。一、先理解 Meteor 3 发生了什么变化Meteor 3 全面转向异步 APIinsertAsync、updateAsync等但find()出于兼容性仍是同步方法——它必须立刻返回 cursor 实例。这直接导致了两个结果before.find钩子必须同步执行否则find()无法同步返回 cursorfind 系列钩子只能挂在 cursor 的异步方法fetchAsync等上触发。这套逻辑封装在 find.js 中同步的 before 钩子在 cursor 创建时立即执行after 钩子则在ASYNC_METHODScountAsync、fetchAsync、forEachAsync、mapAsync被调用后触发。二、find 钩子触发条件完整清单✅ 会触发 find 钩子的方法写法before.findafter.findcollection.find({}).fetchAsync()✅ 立即触发✅ 触发collection.find({}).countAsync()✅ 立即触发✅ 触发collection.find({}).forEachAsync()✅ 立即触发✅ 触发collection.find({}).mapAsync()✅ 立即触发✅ 触发❌ 不会触发 find 钩子的方法写法before.findafter.findcollection.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.findOneawait collection.findOneAsync({})✅ 触发✅ 触发collection.findOne({})❌ 不触发❌ 不触发与 find 不同before.findOne和after.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.jsselector查询条件对象可在 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 起的破坏性变更before.find禁用异步函数v2 之前允许find/findOne 钩子只响应异步方法findOneAsync、fetchAsync等同步调用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),仅供参考
返回列表