Menu
CoddyTech

Генераторы событий

Часть раздела Основы Node.js путешествия по Node.js на Coddy. Урок 29 из 33.

Хранилище должно сообщать о добавлении заметки, не зная, кто хочет об этом услышать.

EventEmitter из node:events хранит список обработчиков для каждого имени события. 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 его вызовет. Ветвь 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..

Попробуй: введи add Buy bread в поле после $ node notes.js и нажми 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