Генераторы событий
Часть раздела Основы 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.
Задание
ЛегкоНа этом шаге открывается подготовленный для курса проект инструмента командной строки для заметок, а не файлы твоего проекта из урока Timers (включая notes.js). Твоя предыдущая работа остаётся в своём уроке. Прочитай предоставленные файлы, прежде чем редактировать store.js. Эта копия содержит команды для заметок и асинхронные функции для работы с файлами.
Хранилище должно сообщать о каждой новой заметке и позволять другому коду решать, что с этим делать. Преврати хранилище в эмиттер событий.
- В
store.jsсделайstoreэкземпляромEventEmitter, который сохраняет все собственные свойства и методы. ИмпортируйEventEmitterизnode:events.new EventEmitter()создаёт новый пустой эмиттер. Скопируй объект хранилища в этот эмиттер с помощьюObject.assign, как показано в уроке. - В
store.js, в методеadd, после сохранения заметок вызови событиеadded, передав два значения: текст заметки и её номер. - В
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;
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Основы Node.js
Потренируйтесь самостоятельно: Песочница Express