1

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

它运行得很好,即使我没有调用 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 方法也应该在第二种情况下执行,因为我没有任何第二个 pre 中间件。

4

2 回答 2

1

mongoose 使用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
于 2020-04-27T20:09:26.697 回答
0

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

当每个中间件调用 next 时,Pre 中间件函数一个接一个地执行。

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

在 mongoose 5.x 中,您可以使用返回 promise 的函数,而不是手动调用 next()。特别是,您可以使用 async/await。

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

在此处阅读有关它的更多信息

于 2021-08-29T11:24:02.890 回答