Menu
CoddyTech

이벤트 이미터

Coddy Node.js 여정의 Node.js 기초 섹션에 포함된 레슨. 33개 중 29번째.

저장소는 누가 듣고 싶어 하는지 몰라도 메모가 추가되었다고 알려야 합니다.

node:events의 EventEmitter는 각 이벤트 이름에 대한 리스너 목록을 유지합니다. on(name, fn)은 리스너를 추가하고, emit(name, ...args)는 해당 이름의 모든 리스너를 그 인수와 함께 즉시 호출합니다. emit이 호출된 뒤에 추가된 리스너는 아무것도 듣지 못합니다.

import { EventEmitter } from 'node:events';

const door = new EventEmitter();
door.on('open', (who) => console.log(`${who} came in`));
door.on('open', () => console.log('Ding!'));
door.emit('open', 'Ada');
// Ada가 들어왔고, 이어서 Ding!

new EventEmitter()는 on과 emit을 가진 객체인 이미터를 만듭니다. 기존 객체에 해당 메서드를 추가하려면 새 이미터에 그 객체의 속성을 복사합니다. Object.assign(new EventEmitter(), { notes: [] })는 notes도 가진 이미터를 반환합니다.

challenge icon

챌린지

쉬움

이 단계에서는 Timers의 프로젝트 파일(notes.js 포함)이 아니라, 강좌에서 준비한 메모 명령줄 도구 프로젝트를 엽니다. 이전 작업은 이전 수업에 그대로 남아 있습니다. store.js를 수정하기 전에 제공된 파일을 읽어 보세요. 이 사본에는 메모 명령과 비동기 파일 도우미가 들어 있습니다.

저장소는 새 메모가 추가될 때마다 이를 알리고, 다른 코드가 이에 대응하는 방법을 결정하게 해야 합니다. 저장소를 이벤트 이미터로 바꾸세요.

  1. store.js에서 store가 자체 속성과 메서드를 모두 유지하는 EventEmitter가 되도록 하세요. EventEmitter를 node:events에서 가져오세요. new EventEmitter()는 비어 있는 새 이미터를 만듭니다. 수업에서 보여 준 것처럼 Object.assign을 사용해 저장소 객체를 해당 이미터에 복사하세요.
  2. store.js의 add에서 메모를 저장한 다음, 두 값을 담아 added 이벤트를 발생시키세요. 두 값은 메모의 내용과 번호입니다.
  3. notes.js에서 저장소의 added 이벤트를 수신하도록 하세요. 리스너는 Saved note , 번호, 마침표를 출력합니다. 명령이 실행되기 전에 이미 수신 중이도록 위쪽 가까이에 연결하세요. 이제 add 분기 자체는 아무것도 출력하지 않고 store.add만 호출합니다.

node notes.js add Buy bread를 실행하면 새 메모의 번호가 포함된 한 줄이 출력됩니다. 예를 들면 다음과 같습니다.

Saved note 3.

clear를 실행한 다음 add Buy milk를 실행하면 Saved note 1.이 출력되고, add Call Ada를 실행하면 Saved note 2.가 출력됩니다.

직접 해보기: $ node notes.js 뒤에 있는 입력란에 add Buy bread를 입력하고 Enter 키를 누르세요. 리스너가 출력한 Saved note와 새 번호가 표시됩니다. 그런 다음 clear, add Buy milk, add Call Ada를 입력하세요. Saved note 1.이 표시된 다음 Saved note 2.가 표시됩니다.

직접 해보기

import { existsSync } from 'node:fs';
import { readFile, writeFile } from 'node:fs/promises';

const file = 'notes.json';

const readJson = async (name, fallback) => {
    if (!existsSync(name)) {
        return fallback;
    }
    try {
        return JSON.parse(await readFile(name, 'utf8'));
    } catch (err) {
        console.error(`${name} is damaged: ${err.message}`);
        process.exit(1);
    }
};

const [notes, settings] = await Promise.all([readJson(file, []), readJson('settings.json', {})]);

const store = {
    notes,
    settings,
    async save() {
        await writeFile(file, JSON.stringify(this.notes, null, 2));
    },
    async add(text) {
        this.notes.push(text);
        await this.save();
        return this.notes.length;
    },
    async remove(n) {
        const [text] = this.notes.splice(n - 1, 1);
        await this.save();
        return text;
    },
};

export default store;
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

Node.js 기초의 모든 레슨

직접 연습해 보세요: Express 플레이그라운드