Как фиксировать события / прослушивать / наблюдать за событиями, исходящими из внутренних функций в nodejs?

#node.js #eventemitter

#node.js #eventemitter

Вопрос:

Я хотел бы запустить кучу кода внутри функций — и функций, вызываемых внутри этих функций, и «всплывать» события без особой работы.

Примечание: я пытаюсь отойти от ООП, больше в функциональное программирование, поэтому я не могу использовать класс implements eventemitter. Я не уверен, нужно ли мне

  • выставить источник событий из каждого объекта — или
  • если я могу просто излучать из одной из внутренних функций и отслеживать событие во внешней функции — или
  • даже просто передать излучатель в качестве параметра функции.

obj2.ts

 import {EventEmitter} from 'events'

export async function obj2(){
    const ev = new EventEmitter()
    ev.emit('test','Yahoo!')
    await new Promise(r => setTimeout(r, 2000));
    ev.emit('test2','Yahoo! - second time')
    ev.emit('test','Yahoo!')
    await new Promise(r => setTimeout(r, 10000));
    ev.emit('test2','Yahoo! - third time')
}
  

obj1.ts

 import {EventEmitter} from 'events'
import { inherits } from 'util'
import {obj2} from './obj2'

async function obj1(){
     await obj2()    
}

inherits(obj1, EventEmitter)

export {obj1}
  

index.js ( точка входа )

 import {obj1} from './obj1'

obj1.on('test', () => { // << this doesn't work obviously 
    //console.log(this)
    console.log('**')
})

obj1()
  

Ответ №1:

Не уверен, зачем вам это нужно obj1 — вы можете просто экспортировать EventEmitter from obj2 и прослушать возвращенный объект:

в obj2.js:

 import {EventEmitter} from 'events'

export const obj2EventEmitter = new EventEmitter();
export async function startEmitting(){
    obj2EventEmitter.emit('test','Yahoo!')
    await new Promise(r => setTimeout(r, 2000));
    obj2EventEmitter.emit('test2','Yahoo! - second time')
    obj2EventEmitter.emit('test','Yahoo!')
    await new Promise(r => setTimeout(r, 10000));
    obj2EventEmitter.emit('test2','Yahoo! - third time')
}
  

в вашем index.js:

 import {obj2EventEmitter, startEmitting} from './obj2';

obj2EventEmitter.on('test', () => {
    console.log('**')
});

(async () => {
    await startEmitting();
})()
  

Комментарии:

1. Это концепция — вот почему я хотел obj1 — это было для того, чтобы увидеть, нужен ли мне объект-эмиттер событий во всех местах, где я излучал события вплоть до поверхности

2. Ну, вам нужно отказаться от объекта-эмиттера, чтобы иметь возможность подключиться к нему. В качестве альтернативы вы можете предоставить интерфейс для подключения к нему. Например. вы могли бы создать функцию в obj1 модуле, которая принимает имя события и обратный вызов и делегирует объект-эмиттер. Это отвечает на ваш вопрос?