자바스크립트 이벤트 리스너 질문

const fs = require(‘fs’);

const writeStream = fs.createWriteStream(’./writeme2.txt’);
writeStream.on(‘finish’, () => {
console.log(‘파일 쓰기 완료’);
});

writeStream.write(‘이 글을 씁니다./n’);
writeStream.write(‘이 글을 한번 더 씁니다./n’);
writeStream.end();


스트림 방식으로 파일쓰기 하는 예제입니다.

end() 메서드가 실행되면
엔진 내부에서 writeStream.on()의 finish 라는 이벤트 리스너를 자동으로 인식하는건가요?

정리하자면, 위 코드에서 어떻게 ‘finish’ 라는 이벤트를 식별하는지가 궁금합니다…

https://nodejs.org/api/events.html

Node.js는 이벤트 리스너를 만들기 위해 EventEmitter 클래스를 제공하고 있습니다. 그리고 이벤트를 읽으려면 주로 EventEmitter.on 또는 EventEmitter.once를 활용하고 있습니다. 그리고 이벤트를 발생시키려면 주로EventEmitter.emit을 쓰고요. fs 라이브러리의 파일 읽기/쓰기 함수도 EventEmitter를 구현한 것입니다.

이벤트 처리 객체는 주로 이벤트 이름과 실행 함수 리스트가 키-값 쌍으로 정해져 있는 맵을 가지고 있는 것으로 구현되는데, 다음과 같이 직접 구현할 수 있습니다.

class MyEventListener {
	constructor () {
		this.eventHashMap = new Map;
	}

	public on(event, callback) {
		// 이벤트 키가 있는지 확인
		// 이벤트 키가 없으면 빈 리스너 리스트를 생성
		if (!this.eventHashMap.has(event)) this.eventHashMap.set(event, []);
		const listeners = this.eventHashMap.get(event);
		// 리스트에 이벤트 리스너 추가
		listeners.push(callback);
		return this;
	}

	public emit(event) {
		const listeners = this.eventHashMap.get(event);
		// 이벤트 리스너가 없으면 false 리턴
		if (!listeners)
			return false;
		// 이벤트 리스너가 있으면 등록된 리스너를 모두 실행하고 true 리턴
		for (const listener of listeners)
			listener();
		return true;
	}
}

이렇게 구현된 EventEmitter 객체에서 emit 메소드가 실행이 된다면 등록된 리스너를 실행할 것입니다.
그렇다면 제시하신 코드에서 writeStream.end()를 실행하면,

  1. WriteStream.prototype.end 안에서 WriteStream.prototype.emit('finish')를 실행
  2. 'finish' 이벤트에 등록돼 있는 리스너를 실행

이렇게 될 것입니다. 리스너에는 () => { console.log('파일 쓰기 완료'); }가 등록돼 있으니 WriteStream.prototype.emit('finish')를 실행하면 작동될 것이기에 정상적으로 실행되는 것이고요.

3개의 좋아요

친절한 답변 너무 감사합니다!!