简介
Objection.js 是一个基于 Node.js 的 ORM 库,可以方便地与各种关系型数据库进行交互。而 objection-events 则是一个为 Objection.js 提供事件支持的 npm 包。通过使用 objection-events,我们可以在 ORM 过程中监听和处理各种事件,可以帮助我们更好地控制数据流程和状态,提高代码的健壮性和可维护性。
安装
在项目中使用 npm 进行安装:
npm install objection-events
基本用法
如何监听事件?
首先,我们需要在 Objection 的 Model 定义中引入 objection-events:
const objection = require('objection'); const objectionEvents = require('objection-events'); class MyModel extends objectionEvents(objection.Model) { static get tableName() { return 'my_table'; } }
此时,MyModel 就可以使用 objection-events 提供的 EventManager 来监听各种事件了。EventManger 是一个单例,负责管理整个应用程序中的事件,无须新建实例。
const eventManager = require('objection-events').EventManager; eventManager.on('insert', MyModel, (ctx, model) => { console.log('Inserted:', model); });
使用 eventManager.on(event, modelClass, handler)
方法即可监听某个 Model 的某个事件。其中 event 是事件名,modelClass 是对应的 Model,handler 是对事件的处理函数。我们可以定义多个 handler 对同一个事件进行处理,它们将在事件触发后依次执行。
如何触发事件?
在 Objection 中,我们可以通过调用 Model 的一些方法来触发相应的事件。例如在新增数据时,我们可以调用 Model 的 $query()
方法:
MyModel.query().insert({name: 'Alice'});
此时,我们在 eventManager.on('insert', MyModel, handler)
中定义的 handler 函数将被自动触发。
事件的上下文
由于同一个事件的处理函数可能存在多个,因此我们需要对事件的上下文进行控制,避免误操作和冲突。
在每个事件中,eventManager 会为处理函数提供一个 Context 对象,包含了事件的上下文信息:
eventManager.on('insert', MyModel, (ctx, model) => { console.log('Inserted:', model, 'by', ctx.user); });
我们在这里为处理函数添加了一个参数 ctx,它是事件上下文,包含了触发事件的一些信息,例如用户信息、请求信息等。
在使用事件时,我们可以通过 eventManager.setContext(ctx)
来设置当前上下文:
eventManager.setContext({user: 'Bob'}); MyModel.query().insert({name: 'Alice'});
此时,ctx.user
将会输出 'Bob'。
事件回调
事件处理函数支持回调机制,可以进行异步操作。
在处理函数中,我们可以调用 ctx.callback()
来通知事件回调:
-- -------------------- ---- ------- ----- --------- - --------------------- ----- --------------- - ---------------------------- ----- ------- ------- -------------------------------- - ------ --- ----------- - ------ ----------- - ------ ----- ------------ - ----- ----- - ----- --------------------- ---- --- -------------------- ------ --- -- - -- ----- - ------------------- -- ---- ---------- ----- - --- ------ ------ - - -------------------------- -------- ----- ------ ----- -- - -- ------ ----------------------- ------- ------- ---
在这里,我们重写了 MyModel 的 create 方法,在插入新数据后,使用 this.emit('created', model, done)
方法触发了一个名叫 'created' 的事件,并附上一个回调函数 done。在处理函数中,我们处理完逻辑后再调用 done(),通知事件回调。
事件拦截器
在事件处理过程中,我们可以使用事件拦截器来对事件进行控制和干预。
在 Objection 中,我们可以使用 beforeInsert
和 afterInsert
等钩子函数来进行插入操作的拦截。与它们类似的还有:beforeUpdate、afterUpdate、beforeDelete、afterDelete。
我们可以在 Model 的静态属性中定义这些钩子:
-- -------------------- ---- ------- ----- --------- - --------------------- ----- --------------- - ---------------------------- ----- ------- ------- -------------------------------- - ------ --- ----------- - ------ ----------- - --------------------------- - -- ------------------------------- - ------ ---------------------------------- - ---- - -- ---------- ------ ------------------ ------------------- ------------- - - -------------------------- - --------------------- ------ ------ --------------------------------- - - --------------------------- -------- ----- ------ -- - ------------------------ ------ ----- ---------- ---
在这里,我们定义了一个 beforeInsert 钩子,在这个钩子中我们判断是否为管理员,只有管理员可进行数据插入,否则会抛出错误。在 $afterInsert
钩子中,我们使用 this.emit('inserted', this)
触发一个 inserted 事件,事件回调会输出插入的数据信息。
示例代码
-- -------------------- ---- ------- ----- --------- - --------------------- ----- --------------- - ---------------------------- ----- ---- - ---------------- ----- ------------ - ----------------------------------------- ----- -- - ------ ------- ---------- ----------- - --------- ---------- - --- ----- ------- ------- -------------------------------- - ------ --- ----------- - ------ ----------- - --------------------------- - -- ------------------------------- - ------ ---------------------------------- - ---- - -- ---------- ------ ------------------ ------------------- ------------- - - -------------------------- - --------------------- ------ ------ --------------------------------- - - --------------------------- -------- ----- ------ -- - ------------------------ ------ ----- ---------- --- ------ -- -- - ----- --------------------------------- ----- -- - ----------------------- --------------------- --- -- ----- ------------------------------ ------ ---- ------ --------- --------- ----- ----------------------------- ---------- -- ----- ------------------------------ ------------- -----
以上代码演示了如何在 Objection.js 中使用 objection-events,我们定义了一个 MyModel,并在 beforeInsert 钩子中对普通用户进行了禁止插入的控制,在 afterInsert 钩子中触发了一个 inserted 事件,在事件回调中输出了插入的数据信息。最后使用 async/await 方式插入了一条数据,并输出了相应的日志。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/600668f4d9381d61a3540e49