问题 如何在mongoose中间件中发出事件?


我希望在新博客保存时发出事件

blog.post('save',function(blog){
    this.emit('newBlog',blog)
})

在我的项目的其他地方说app.js可以听这个事件

EventEmitter  = require('events').EventEmitter;
emitter = new EventEmitter();

emitter.on('newBlog',function(blog){
    console.log(blog);
})

这个怎么做?


10833
2018-06-01 09:22


起源



答案:


事件发射器的工作方式是你必须使用 相同 事件发射器对象侦听您曾经发射的事件。所以你需要这样的东西:

要在项目的不同部分之间共享,您应该创建一个模块,并在需要的地方需要它。

my-event.js:

var eventEmitter = new require('events').EventEmitter();
module.exports = eventEmitter; 

然后你 require 这个 eventEmitter 无论你想在哪里使用它

blog.js:

var myEvent = require('../my-event');
blog.post('save',function(blog){
    myEvent.emit('newBlog', blog);
});

app.js:

var myEvent = require('./my-event');
myEvent.on('newBlog', console.log);

如果您不想遇到创建和需要自己的模块的麻烦,可以使用全局模块 process 这也是一个EventEmitter。

anywhere:

process.on('my-custom-event', myCustomHandler);

anywhere-else:

process.emit('my-custom-event', data);

虽然公平 警告:你正在污染全球范围。如果某些其他模块也在使用相同的事件名称,那么您就会发生冲突,这种冲突可能以意想不到的方式出现,甚至更难调试。


9
2018-06-01 13:01



我认为mongoose模式继承自EventEmitter,所以我可以做到 this.emit('newBlog',blog) 代替 eventEmitter.emit('newBlog',blog);,但事件监听器将无法正常工作。而且我想如果每当我需要使用它时我必须传递相同的事件发射器,那么重点是什么?我可以用实际的业务逻辑替换事件来为我省去一大堆麻烦。 - paynestrike
@paynestrike这一点正在脱钩。这意味着发出的东西不必知道所有正在倾听的事情。 - Aaron Dufour
@AaronDufour然后如何将我的模型中的eventEmitter传递给app.js? - paynestrike
@paynestrike您必须从模型文件中导出它并从app.js中获取它。 - Aaron Dufour
@paynestrike结帐更新 - laggingreflex


答案:


事件发射器的工作方式是你必须使用 相同 事件发射器对象侦听您曾经发射的事件。所以你需要这样的东西:

要在项目的不同部分之间共享,您应该创建一个模块,并在需要的地方需要它。

my-event.js:

var eventEmitter = new require('events').EventEmitter();
module.exports = eventEmitter; 

然后你 require 这个 eventEmitter 无论你想在哪里使用它

blog.js:

var myEvent = require('../my-event');
blog.post('save',function(blog){
    myEvent.emit('newBlog', blog);
});

app.js:

var myEvent = require('./my-event');
myEvent.on('newBlog', console.log);

如果您不想遇到创建和需要自己的模块的麻烦,可以使用全局模块 process 这也是一个EventEmitter。

anywhere:

process.on('my-custom-event', myCustomHandler);

anywhere-else:

process.emit('my-custom-event', data);

虽然公平 警告:你正在污染全球范围。如果某些其他模块也在使用相同的事件名称,那么您就会发生冲突,这种冲突可能以意想不到的方式出现,甚至更难调试。


9
2018-06-01 13:01



我认为mongoose模式继承自EventEmitter,所以我可以做到 this.emit('newBlog',blog) 代替 eventEmitter.emit('newBlog',blog);,但事件监听器将无法正常工作。而且我想如果每当我需要使用它时我必须传递相同的事件发射器,那么重点是什么?我可以用实际的业务逻辑替换事件来为我省去一大堆麻烦。 - paynestrike
@paynestrike这一点正在脱钩。这意味着发出的东西不必知道所有正在倾听的事情。 - Aaron Dufour
@AaronDufour然后如何将我的模型中的eventEmitter传递给app.js? - paynestrike
@paynestrike您必须从模型文件中导出它并从app.js中获取它。 - Aaron Dufour
@paynestrike结帐更新 - laggingreflex


如果从文档(特定模式的实例)发出事件,则必须侦听此实例以接收事件。

如果要全局侦听所有实例生成的所有事件,则必须从Schema中发出事件。

blog.post('save',function(blog){
    blog.schema.emit('newBlog',blog)
})

例如,在app.js中,您可以侦听架构上的事件:

Blog.schema.on('newBlog',function(blog){
    console.log(blog);
})

3
2018-06-09 20:23



你尝试过你的方法吗,我做了,它不起作用。this.schema 未定义。 - paynestrike
对不起,我没有使用post hooks进行测试,但是我知道如果你有一个文件实例就可以了。所以你可以通过blog.schema替换this.schema。它应该工作 - Julien Bachmann
@paynestrike,你成功通知了吗? - Julien Bachmann