javascript 使用nodejs事件模块时出现意外的同步行为

pexxcrt2  于 2023-01-04  发布在  Java
关注(0)|答案(1)|浏览(98)

我使用节点事件模块异步执行我的函数。

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

eventEmitter.on('myEvent', f2);

function f1(x, y) {
    console.log('got', x, y)

    eventEmitter.emit('myEvent', x, y);
    eventEmitter.emit('myEvent', x, y);
    eventEmitter.emit('myEvent', x, y);

    console.log('done')
}

var count = 0
function f2(x, y) {
    count++;
    console.log('from f2', x, y, count)
}

f1(1, 2)

其输出为

alok@alok-HP-Laptop-14s-cf3xxx:~/tmp/test-node$ node alok.js 
got 1 2
from f2 1 2 1
from f2 1 2 2
from f2 1 2 3
done

我的预期输出为

got 1 2
done
from f2 1 2 1
from f2 1 2 2
from f2 1 2 3

为什么console.log('done')在最后运行。或者为什么执行是同步的?

u5rb5r59

u5rb5r591#

因为事情就是这样的:
EventEmitter对象发出一个事件时,附加到该特定事件的所有函数都被 * 同步地 * 调用。
[..]

异步与同步

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

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

https://nodejs.dev/en/api/v19/events

相关问题