在猫鼬中预存中间件

pre save middleware in mongoose

我是第一次使用预保存中间件,有点困惑。

它运行得很好,而且我的保存方法正在执行,即使我没有调用 next()

案例 1

tourSchema.pre('save', function () {
  console.log('first middleware is getting called');
})

但是当我这样做时,当 next 在函数参数内声明但我不调用 next() 它挂在那里并且保存方法没有被执行

案例 2

tourSchema.pre('save', function (next) {
  console.log('first middleware is getting called');
});

但是只要我调用 next() 它就会被执行

案例 3

tourSchema.pre('save', function (next) {
  console.log('first middleware is getting called');
  next()
});

所以我只想知道第二种情况有什么问题。在此我只有并且只有这个预中间件。 如何在函数参数中定义 next 很重要,在第二种情况下也应该执行 save 方法,因为我没有任何第二个预中间件。

猫鼬使用 kareem 库来管理钩子。

kareems 使用钩子函数的 length 属性 来确定 next 是否定义为参数。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length

您的第一个函数没有参数,kareem 将假定这是一个同步函数

const firstFunction = function () {
  console.log('first middleware is getting called');
})
console.log(firstFunction.length) // this will output 0

你的第二个函数有 1 个参数,kareem 库会看到你的函数接受 next 个参数。它将传递一个回调并在 next 函数中执行它。由于从未调用 next,因此永远不会调用该回调。

const secondFunction = function (next) {
  console.log('first middleware is getting called');
})
console.log(secondFunction.length) // this will output 1

thammada 的回答完美地解释了你的问题,我只想补充说你实际上可以使用异步函数来逃避调用 next()

的义务

Pre middleware functions are executed one after another, when each middleware calls next.

`const schema = new Schema(..);
 schema.pre('save', function(next) {
   // do stuff
   next();
 });`

In mongoose 5.x, instead of calling next() manually, you can use a function that returns a promise. In particular, you can use async/await.

schema.pre('save', function() {
  return doStuff().
  then(() => doMoreStuff());
});

Read more about it here