Javascript 是node.js事件';调用堆栈为空时执行的s处理程序?

Javascript 是node.js事件';调用堆栈为空时执行的s处理程序?,javascript,node.js,Javascript,Node.js,我曾经认为与node.js事件相关的代码是异步的。但下面的例子并不坚持这一点: var EventEmitter = require('events').EventEmitter; var emitter = new EventEmitter(); emitter.on('foo', function () { console.log('Foo handler'); }); emitter.emit('foo'); console.log('Synchronous code!');

我曾经认为与node.js事件相关的代码是异步的。但下面的例子并不坚持这一点:

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

emitter.on('foo', function () {
    console.log('Foo handler');
});
emitter.emit('foo');

console.log('Synchronous code!');
“foo”事件应添加到eventQueue中,并在主函数之后处理。但“同步代码”显示在“Foo处理程序”之前。为什么?


emitter.emit()引发的事件是否被推送到节点中的eventsQueue?如果否,哪些会导致事件循环

emitter.on
emitter.emit
将在执行此上下文后安排

就像你在做的那样:

setImmediate(() => console.log('after Sync code in this context'))
console.log('Synchronous code!')
另一个例子

'use strict'

// handlers are executed in the order in which they are registered

console.log('Expected order: 1 2 a c b')

process.on('asd', () => console.log('a'))

function test () {
  setTimeout(() => {
    process.on('asd', () => console.log('b'))
  }, 100)

  process.on('asd', () => console.log('c'))

  setTimeout(() => {
    process.emit('asd')
  }, 200)

  console.log('2')
}

console.log('1')

test()
并非JS或Node JS中的所有回调都是异步的

示例数组排序、映射、约简等 在报告中明确提到

EventEmitter按照中的顺序同步调用所有侦听器 他们是注册的


因此您得到了这种行为。

setImmediate()
在Node.js事件循环的这一轮结束时调用回调。但是我要说的是,最后一个
控制台
语句是同步部分,事件队列中的任何内容都不应该在它之前执行。由
emitter.emit()
引发的事件是否被推送到节点中的事件队列中?
事件队列中的任何内容都不应该在它之前执行,这就是正在发生的事情。在事件管理之前执行console.log。也许我不明白,对不起:“‘管理’是什么意思?”?我的意思是在console.log之前调用事件处理程序(不是您所指的“管理”)的顺序是:
emitter.on
handler在节点进程内存中注册,
emitter.emit
被认为是异步的,因此将在执行当前上下文之后执行,最后执行
控制台.log
。更清楚吗?我的意思是,我看不出问题:什么是sync是在异步操作之前执行的emitter.emit()引发的事件会被推送到节点中的eventsQueue吗?如果您要对它们使用setImmediate或setInterval,那么是的,因为它们只在调用堆栈中执行,而不在eventqueue中等待。所以这些函数(设定间隔等)是将事件放入eventsQueue的,而不是所有事件都经过它吗?基本原理是我们有单线程事件循环,我们希望用它来执行所有事情,所以任何像setInterval、setImmediate或任何需要时间处理的api调用都会转移到事件队列,这样我们的调用堆栈就可以重新启动ns empty来执行不需要时间的代码。当这些进程完成
事件循环时
将它们再次转移到调用堆栈并执行它们的回调。此外,回调只不过是在给定任务完成时调用的函数。我在这里提到的描述只是基本概述,有一个重新定义web API(在浏览器中)和其他部分超出范围的库。