我使用EventEmitter如下:
const EventEmitter = require('events');
const myEmitter = new EventEmitter();
function c2(num) {
return new Promise((resolve) => {
resolve(`c2: ${num}`);
});
}
// eslint-disable-next-line no-underscore-dangle
// eslint-disable-next-line no-console
const doSomeStuff = async (number) => {
try {
console.log(`doSomeStuff: ${number}`);
const r2 = await c2(number);
console.log(r2);
} catch (err) {
throw err;
}
};
myEmitter.on('eventOne', async (n) => {
await doSomeStuff(n);
});
myEmitter.emit('eventOne', 1);
myEmitter.emit('eventOne', 2);
myEmitter.emit('eventOne', 3);
myEmitter.emit('eventOne', 4);
我希望得到一个结果
doSomeStuff: 1
c2: 1
doSomeStuff: 2
c2: 2
doSomeStuff: 3
c2: 3
doSomeStuff: 4
c2: 4
但是输出显示了我
doSomeStuff: 1
doSomeStuff: 2
doSomeStuff: 3
doSomeStuff: 4
c2: 1
c2: 2
c2: 3
c2: 4
据我了解,EventEmitter
同步调用事件回调函数,但是由于某种原因,在调用下一个回调函数之前,该回调函数尚未完成执行。我想我这里缺少一些非常基本的东西。
答案 0 :(得分:2)
事件处理程序不关心函数的async
性质。实际上,它根本不关心返回值。只要听到事件,它就会尽快调用它,并且每次听到事件时,它将继续触发。不管它是否已经在运行一个函数。
myEmitter.on('eventOne', async (n) => {
await doSomeStuff(n);
});
实际上与没有异步/等待的情况完全相同:
myEmitter.on('eventOne', (n) => {
doSomeStuff(n);
});
假设,您可以稍微调整代码,以便您执行以获取期望的输出。但是,您需要引入单数路径上下文,以使每个发射器都影响一件事情,而不是每个事件都触发其自己的doSomeStuff
实例。这是使用生成器函数的示例:
// EventEmitter Polyfill
class EventEmitter {
constructor() {this._listeners = new Map();}
on(e, cb) {this._listeners.set(e, [...(this._listeners.get(e) || []), cb]);}
emit(e, payload) {for (const listener of (this._listeners.get(e) || [])) listener(payload);}
}
const myEmitter = new EventEmitter();
function c2(num) {
return new Promise(resolve => {
resolve(`c2: ${num}`);
});
}
async function* doSomeStuff() {
while (true) {
try {
const number = yield;
console.log(`doSomeStuff: ${number}`);
const r2 = await c2(number);
console.log(r2);
} catch (err) {
throw err;
}
}
}
const someStuff = doSomeStuff();
someStuff.next(); // Start it
myEmitter.on("eventOne", n => {
someStuff.next(n);
});
myEmitter.emit("eventOne", 1);
myEmitter.emit("eventOne", 2);
myEmitter.emit("eventOne", 3);
myEmitter.emit("eventOne", 4);
答案 1 :(得分:1)
按照上述逻辑,这是我的意见:
//You emitted event asynchronous, so the listeners will be called asynchronous in [A] scope
myEmitter.emit('eventOne', 1); // all
myEmitter.emit('eventOne', 2); // of
myEmitter.emit('eventOne', 3); // us
myEmitter.emit('eventOne', 4); // start at almost the same time.
// In listener:
await doSomeStuff(n); // I run synchronously inside [event 1] scope, not [A] scope
await doSomeStuff(n); // I run synchronously inside [event 2] scope, not [A] scope
await doSomeStuff(n); // I run synchronously inside [event 3] scope, not [A] scope
await doSomeStuff(n); // I run synchronously inside [event 4] scope, not [A] scope
,其余的将异步解决。
简述:事件会异步发出,因此监听器没有理由 SYNC 连续发
。