【问题标题】:How mongoose middleware works and what is next()?mongoose 中间件是如何工作的,next() 是什么?
【发布时间】:2020-12-27 06:42:42
【问题描述】:
userSchema.pre('save',async function(next){
   //hash the password before saving user to database
   next()
})

大家好,我正在尝试理解 mongoose 中的中间件的概念。假设我有一个 userSchema,我在将用户保存到数据库之前运行 pre hook 以散列密码。从表面上看,据我了解,我拥有的上述代码将对密码进行哈希处理(不是这个问题的重要部分),然后调用 next() 来表示该函数已完成。但是,我试图了解事情在幕后是如何运作的。我想知道 next() 是什么?你们能否带我看一个例子,说明一旦代码执行,一切如何从头到尾协同工作,或者以某种方式帮助我更好地理解这个概念?谢谢

【问题讨论】:

  • 这能回答你的问题吗? What is the parameter "next" used for in Express?
  • 每当您对数据库执行操作时都会触发 mongoose 中间件,在上面的示例中,每当您对用户集合执行保存操作时,回调函数将在执行保存操作之前执行(因为它是一个前置中间件)。下一个只是意味着不阻止执行并继续执行下一个 mongoose 中间件(如果存在)或您的​​实际保存操作。你的中间件应该总是调用 next() 否则你的代码会被阻塞。
  • 所以我假设实现了 mongoose API,以便在这种情况下调用 next() 对吗?下一个功能是猫鼬给我的。

标签: mongodb mongoose mongoose-schema


【解决方案1】:

简短:使用pre 方法,您可以为模式的某些事件注册侦听器。因此,每当您保存所述模型的文档时,pre('save', callback) 都会触发。 pre 表示它将在事件之前执行,因此可以使用它(例如)在将密码保存到文档之前对其进行哈希处理。

但是,您有几个选项来定义它们,见下文:

使用async 回调函数和提供next 参数的组合不是必需的,您可以:

使用普通回调和下一个参数

next 参数是 mongoose 提供给您的一个函数,用于让您有出路,或者告诉 mongoose 您已完成并继续执行链中的下一步。也可以将Error 传递给next,它将停止执行链。

schema.pre('save', function(next) {
  // do stuff
  
  if (error) { return next(new Error("something went wrong"); }
  return next(null);
});

使用异步回调

在这里,一旦您的异步回调完成,执行链将继续。如果出现错误并且您想中断/停止执行链,您只需 throw 即可

schema.pre('save', async function() {
  // do stuff
  await doStuff()
  await doMoreStuff()

  if (error) { throw new Error("something went wrong"); }
  return;
});

直接来自文档:https://mongoosejs.com/docs/middleware.html#pre

示例

const { Schema, model }  = require('mongoose');

const SomeSchema = new Schema ({
  name : { type : String }
});

SomeSchema.pre('save', function (next) {
  console.log('pre save fired!');
  return next();
});

const Some = model('Some', SomeSchema);

console.log('before create');
const doc = new Some({ name : 'test' });
doc.save((err) => {
  console.log('after saved');
});

这将输出

before create
pre save fired!
after saved

【讨论】:

  • 嘿,帕斯卡,这很有帮助。我还有一个问题。为什么使用异步函数不再需要下一个回调?这和async函数的本质有关系,就是总是返回一个promise,这样当async函数返回时,下一步就可以处理promise了?
  • Mongoose 知道您指定的回调。因此,如果回调返回一个 Promise(异步函数),mongoose 将等待该 Promise 被解析或拒绝。如果是普通函数,则需要调用 next 否则链会挂起
  • 很高兴我能帮上忙!
  • 如果还有什么不清楚的地方告诉我,否则请采纳为正确答案!谢谢!
猜你喜欢
  • 2021-07-05
  • 2015-05-15
  • 2019-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-07
  • 1970-01-01
  • 2019-04-07
相关资源
最近更新 更多