Eventemitter 代码是否阻塞

Is Eventemitter code blocking or not

我正在做一个项目,我有一个 Feeds 页面,显示所有用户的所有类型 post。键入特定列表页面和 Posts 的详细信息页面。

页数- 1. 饲料 2. 列表(具体类型) 3.细节(细节post)

所以我有关注 Mongo collection - 1.饲料 2. type1 post 3. type2 post 4. type3...

现在,当用户 post 一个新的 Post 我将其保存到相应的 collection 让浏览器 'type1 post' 和 return 成功。但我也想用相同的数据更新我的 'Feed' collection。我不希望它在发送响应之前完成。因为那会增加用户的等待时间。因此我使用了事件。这是我的代码 -

const emitter = new event.EventEmitter();

function savePost(){
    //  Code to save data to Mongo collection

    emitter.emit('addToFeeds', data);
    console.log('emit done');

    return res.json(data);
}

emitter.on('addToFeeds', function(data){
    // code to save data to Feeds collection
    console.log('emitter msg - ', data);
});

现在,当我检查 console.log 输出时,它首先显示 "emitter msg -",然后显示 "emit done"。这就是为什么我假设 emitter.on 代码在 res.json(data);

之前执行

现在我想知道事件是否会阻塞代码?如果我必须在后台或发送响应后更新提要,正确的方法是什么?将来我还想实现缓存,所以我也必须在添加 post 时更新缓存,这也是我想在发送响应后或在后台执行的操作。

事件是同步的,会阻塞。这样做是为了让您可以按特定顺序绑定事件并按该顺序级联它们。您可以使每个项目异步,如果您在这些事件中发出 HTTP 请求,那将发生异步,但事件本身是同步启动的。

参见:https://nodejs.org/api/events.html#events_emitter_emit_eventname_args

并且:https://nodejs.org/api/events.html#events_asynchronous_vs_synchronous

是的,事件是同步和阻塞的。它们是通过简单的函数调用实现的。如果您查看 eventEmitter 代码,要向所有侦听器发送事件,它实际上只是遍历一组侦听器并依次调用每个侦听器回调。

Now I'm wondering does Events are blocking code?

是的。在 doc for .emit() 中,它表示:"Synchronously calls each of the listeners registered for the event named eventName, in the order they were registered, passing the supplied arguments to each."

并且,本节 Asynchronous vs. Synchronous 文档中的更多信息是这样说的:

EventEmitter按照注册的顺序同步调用所有的监听器。这对于确保事件的正确排序并避免竞争条件或逻辑错误很重要。在适当的时候,侦听器函数可以使用 setImmediate() 或 process.nextTick() 方法切换到异步操作模式:

If I have to update Feeds in background or after response is sent what is the right way?

如果它希望其他侦听器和其他同步代码完成 setTimeout()setImmediate()process.nextTick() ,您的 eventListener 可以安排何时真正执行其代码 运行ning 在它开始工作之前。因此,您注册了一个普通的侦听器(它将被同步调用),然后在其中可以使用 setTimeout()setImmediate()process.nextTick() 并将实际工作放入该回调中。这将延迟 运行ning 您的代码,直到触发初始事件的当前 Javascript 完成 运行ning。

对于纯 Javascript 代码,node.js 中没有实际的 "background processing"。 node.js 是单线程的,因此当您 运行 宁一些 Javascript 时,没有其他 Javascript 可以 运行。实际的后台处理必须通过现有的异步操作(使用本机代码在后台 运行 进行操作),例如网络 I/O 或磁盘 I/O)或通过 运行使用另一个进程来完成工作(其他进程可以是任何类型的代码,包括另一个 node.js 进程)。