Mongoose 中如何使用生命周期钩子函数

阅读时长 8 分钟读完

Mongoose 是 Node.js 环境下一个非常流行的 MongoDB 驱动程序,它提供了许多方便的特性来简化 MongoDB 数据库操作。其中生命周期钩子函数就是 Mongoose 中提供的一种非常有用的特性,它可以让我们在文档的保存、更新、删除和查询等过程中执行一些额外的操作,比如验证数据、处理敏感信息等。本文将详细介绍 Mongoose 中如何使用生命周期钩子函数,包括其 API、参数、执行顺序和常用场景等。

生命周期钩子函数 API

Mongoose 中定义了 4 个生命周期钩子函数,分别对应了文档对象的保存、更新、删除和查询操作,它们的名称和触发时机如下:

  • pre('save', callback): 在文档保存之前触发。
  • pre('update', callback): 在文档更新之前触发。
  • pre('findOneAndUpdate', callback): 在文档查询并更新之前触发。
  • pre('remove', callback): 在文档删除之前触发。

在触发生命周期钩子函数时,Mongoose 会将钩子函数中传递的回调函数作为 next 参数传递进去,我们可以在回调函数中执行自定义的操作,然后调用 next 函数继续执行后续的操作。

生命周期钩子函数参数

生命周期钩子函数的回调函数中有两个参数:nextdone

  • next: 代表下一步执行的函数,如果在回调函数中不调用 next 函数,则后续的操作将无法执行。在保存和更新操作中,Mongoose 默认会调用 next 函数,但在查询操作中,需要手动调用 next 函数才能继续执行查询操作。
  • done: 用于指示回调函数已经执行完毕,可以在回调函数中直接返回。

生命周期钩子函数执行顺序

在 Mongoose 中,生命周期钩子函数的执行顺序是按照它们定义的顺序依次执行的。例如,在文档保存操作上,如果先定义了 pre('save', [callback1]),再定义了 pre('save', [callback2]),那么 callback1 将先于 callback2 执行。注意,如果某个钩子函数中没有调用 next 函数,则后续的钩子函数将无法执行。

常用场景

下面列举了几种常见的使用场景,以便大家更好地理解生命周期钩子函数的具体应用。

数据验证

在保存或更新文档之前,我们可以使用生命周期钩子函数来验证文档的数据是否符合规范。例如,我们可以通过 pre('save', callback) 钩子函数来验证文档中必填的字段是否存在,并给出相应的错误提示,避免无效数据写入数据库。

举个例子,考虑一个 User 模型的定义,包含了 name 和 email 两个属性:

-- -------------------- ---- -------
----- ---------- - --- -----------------
  ----- -
    ----- -------
    --------- ----
  --
  ------ -
    ----- -------
    --------- -----
    ---------- -----
    ------- -----
    --------- -
      ---------- ------- -- -
        ------ -------------------------
      --
      -------- -------- ----- --------
    -
  -
---

我们可以在保存文档之前,使用 pre('save', callback) 钩子函数来进行数据验证:

-- -------------------- ---- -------
---------------------- -------- ------ -
  ----- ---- - -----
  -- ----------- -- ------------ -
    -- --------------------
    ------ -------- -------------- ---- -- ---------
  -
  ------------------------------- -------- ----- -
    -- ----- -
      -- --------------------
      ------ ----------
    -
    -- ------------
    -------
  ---
---

这里的 validatePassword 函数可以用来对用户密码进行加密和验证,避免将用户密码明文保存在数据库中。

动态默认值

在 Mongoose 中,我们可以使用 default 属性为文档属性设置默认值,例如:

-- -------------------- ---- -------
----- ---------- - --- -----------------
  ----- -
    ----- -------
    --------- ----
  --
  ----------- -
    ----- -----
    -------- --------
  -
---

但是有时候,我们需要将默认值设置为一个动态的值,例如当前时间、当前用户等。此时,我们可以使用生命周期钩子函数来实现:

这里我们在保存文档之前,判断 created_at 是否存在,如果不存在,则设置为当前时间。

处理敏感信息

在保存或更新文档之前,我们可以使用生命周期钩子函数对敏感信息进行处理,例如对密码进行加密,对身份证号进行脱敏。这样可以保证敏感信息不被明文存储在数据库中。

-- -------------------- ---- -------
---------------------- -------- ------ -
  ----- ---- - -----
  -- ----------------------------- -
    ------------------ -------- ----- ----- -
      -- ----- -
        ------ ----------
      -
      -------------------------- ----- -------- ----- ----- -
        -- ----- -
          ------ ----------
        -
        -- --------------
        ------------- - -----
        -------
      ---
    ---
  - ---- -
    -------
  -
---

这里的 bcrypt 库是用来对密码进行加密的,它可以保证密码不被明文保存在数据库中。

示例代码

下面是使用 pre('save', callback) 钩子函数保存文档的示例代码,其中采用了数据验证和密码加密两个操作:

-- -------------------- ---- -------
----- -------- - --------------------
----- ------ - ------------------

-- -- ---- ---
----- ---------- - --- -----------------
  ----- -
    ----- -------
    --------- ----
  --
  ------ -
    ----- -------
    --------- -----
    ---------- -----
    ------- -----
    --------- -
      ---------- ------- -- -
        ------ -------------------------
      --
      -------- -------- ----- --------
    -
  --
  --------- -
    ----- -------
    --------- -----
    ---------- -
  -
---

-- -------
-------- ---------------------- --------- -
  ------------------ -------- ----- ----- -
    -- ----- -
      ------ --------------
    -
    --------------------- ----- ----------
  ---
-

-- -----------
---------------------- -------- ------ -
  ----- ---- - -----
  -- ----------------------------- -
    -- --------
    --------------------------- -------- ----- ----- -
      -- ----- -
        ------ ----------
      -
      -- --------------
      ------------- - -----
      -------
    ---
  - ---- -
    -------
  -
---

-- -- ---- --------
----- ---- - ---------------------- ------------
----- ---- - --- ------
  ----- -------
  ------ -------------------
  --------- --------
---
------------------ ----- -
  -- ----- -
    -------------------
  - ---- -
    ------------------------- ----- --------
  -
---

总结

生命周期钩子函数是 Mongoose 中非常有用的一个特性,可以在文档的保存、更新、删除和查询等操作中执行一些额外的操作,比如数据验证、动态默认值、处理敏感信息等。本文中我们介绍了生命周期钩子函数的 API、参数、执行顺序和常见应用场景,并给出了示例代码。掌握生命周期钩子函数的使用方法,可以大大简化复杂数据操作的流程,提高开发效率。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64f30e7df6b2d6eab3c925ba

纠错
反馈