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()
를 실행하면,
-
WriteStream.prototype.end
안에서 WriteStream.prototype.emit('finish')
를 실행
-
'finish'
이벤트에 등록돼 있는 리스너를 실행
이렇게 될 것입니다. 리스너에는 () => { console.log('파일 쓰기 완료'); }
가 등록돼 있으니 WriteStream.prototype.emit('finish')
를 실행하면 작동될 것이기에 정상적으로 실행되는 것이고요.
3개의 좋아요