NodeJS 为什么Mongoose预钩子不能使用胖箭头函数语法

lpwwtiir  于 2023-06-29  发布在  Node.js
关注(0)|答案(2)|浏览(134)

我尝试使用一个简单的预挂接Mongoose来删除文档的任何引用,如下所示:

PostSchema.pre("remove", async () => {
  await Comment.remove({ _postId: this._id }).exec();
  await User.update({ $pull: { _posts: this._id } }).exec();
});

上面的胖箭头语法似乎不起作用--尽管Post文档被删除了,但Comment和User模型并没有相应地更新。相反,我不得不使用旧的语法(根据mongoose文档)来让钩子正常工作,比如:

PostSchema.pre("remove", async function() {
  await Comment.remove({ _postId: this._id }).exec();
  await User.update({ $pull: { _posts: this._id } }).exec();
});

我觉得这很奇怪,除非我做错了什么。这是预期的行为吗?

bxpogfeg

bxpogfeg1#

因为this指向全局范围,而不是箭头函数中的函数范围。在这种情况下,请使用function(){}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
编辑:类似问题:https://stackoverflow.com/a/49441708/7526159

r1zhe5dt

r1zhe5dt2#

Mongoose pre-hooks,也称为中间件功能,用于在Mongoose模型上执行特定操作之前或之后执行代码,例如保存或验证文档。这些钩子允许您在执行操作之前修改数据、执行附加操作或验证某些条件。
在Mongoose中,可以使用传统的函数语法或fat-arrow(箭头函数)语法来定义pre-hooks。然而,这两种语法之间有一个关键的区别,这会影响它们在Mongoose pre-hooks上下文中的行为。
当您使用传统的函数语法定义一个pre-hook时,函数中的this关键字引用了正在操作的文档或模型。这允许您使用Mongoose API访问和操作文档的数据或执行其他操作。
但是,当您使用胖箭头函数语法时,this的值不会根据文档或模型的上下文动态确定。相反,它保留了定义函数的周围范围中的this的值。在大多数情况下,这将引用全局对象(例如,浏览器中的window或Node.js中的global)。
因此,当您使用胖箭头函数语法定义Mongoose pre-hook时,this关键字将不会引用正在操作的文档或模型。因此,您将无法访问文档的属性,也无法在pre-hook中使用Mongoose API执行操作。
下面是一个例子来说明区别:

// Traditional function syntax
schema.pre('save', function (next) {
  // Access document properties using `this`
  console.log(this.name);
  next();
});

// Fat-arrow function syntax
schema.pre('save', (next) => {
  // `this` does not refer to the document
  // Cannot access document properties using `this`
  // console.log(this.name); // Error: Cannot read property 'name' of undefined
  next();
});

总而言之,Mongoose预钩子不能使用胖箭头函数语法,因为this的值并不引用正在操作的文档或模型,这使得在预钩子中无法访问文档的属性或使用Mongoose API。为了有效地使用pre-hook,建议使用传统的函数语法。

相关问题