emit()方法是异步执行的吗?
发布于 8 年前 作者 JerrysShan 9233 次浏览 来自 问答

var events=require(“events”); exports.index=function(req,res,next){ var ep=new events.EventEmitter(); ep.on(“hello”,function(){ console.log(“hello”); }); console.log(“21312”); ep.emit(“hello”);//触发事件,执行事件的处理函数和下面的代码是异步执行的吗 console.log(“world”); res.send(‘hello world’); }

6 回复

楼主同学,请记住一个最基本的定律,在nodejs里没有一行js代码是异步执行的。回调和异步没有半毛钱关系,回调恰恰是用来保证同步的。

var fs = require('fs')

function test(){
var a = 0;

fs.readFile('t1.txt', function(err, data){
  if (err) throw err;
  a++;
  console.log('in: ' + a);
});

console.log('out: ' + a);
}

test();

你认为a是多少?如果你不运行就能清楚的知道a的值,那说明你已经真正理解了js的回调异步。

如果你想更深入的理解,mozilla的文档是非常好的,它清楚的告诉了我们js事件(回调)执行的时机。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/EventLoop

注意官方文档,明确说明是同步的:

Asynchronous vs. Synchronous

The EventListener calls all listeners synchronously in the order in which they were registered. This is important to ensure the proper sequencing of events and to avoid race conditions or logic errors. When appropriate, listener functions can switch to an asynchronous mode of operation using the setImmediate() or process.nextTick() methods:

const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
  setImmediate(() => {
    console.log('this happens asynchronously');
  });
});
myEmitter.emit('event', 'a', 'b');

链接:Events

ep.emit(“hello”) 直接进入执行栈,立即执行的;想一向如果是异步,那么什么时候“hello”真正发生就变得不可预期了,就像setTimeout(fn, timeout)那样,timeout基本准确,但有误差。

io操作都是异步 cpu操作都是同步

@coordcn 我只是疑问,事件为什么是jS中异步编程的一种,也就是说事件为什么是异步的,如果这里我改成一个函数调用,貌似也能达到效果。

@JerrysShan

事件是事件,异步是异步,这两者没有关系。

事件可以是同步的,也可以是异步的,异步可以用事件模型来驱动,也能用普通函数调用来驱动,引入协程之后,回调都不是必须的,完全可以用同步代码去写异步程序。

事件在某些情况下表达得相对清晰。

我上面的例子如果用lua了写就会变得很容易理解

local fs = require('fs')

function test()
local a = 0

-- 这里的fs.readFile是异步的,调用过程会让出当前协程的执行权,注册异步完成后的回调函数,在回调函数内会恢复协程的执行权,并将回调结果返回。
-- 这跟generator/yield或async/await是类似的,但比js要清晰简单得多。
-- 以这种模式编写异步程序,就完全不需要考虑事件,回调等问题,跟写同步程序是没有差别的
local data, err = fs.readFile('t1.txt')

a = a + 1

print(a)

end

test()
回到顶部