Menu
CoddyTech

Emisores de eventos

Parte de la sección Conceptos básicos de Node.js del Journey de Node.js de Coddy. Lección 29 de 33.

La tienda debería anunciar que se ha añadido una nota sin saber quién quiere enterarse.

Un EventEmitter de node:events mantiene una lista de escuchas para cada nombre de evento. on(name, fn) añade una escucha; emit(name, ...args) llama a todas las escuchas de ese nombre inmediatamente, con esos argumentos. Una escucha añadida después de la emisión no oye nada.

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 entró, luego Ding!

new EventEmitter() crea un emisor, un objeto que tiene on y emit. Para dar esos métodos a un objeto existente, copia sus propiedades en un emisor nuevo: Object.assign(new EventEmitter(), { notes: [] }) devuelve un emisor que también tiene notes.

challenge icon

Desafío

Fácil

Este paso abre el proyecto preparado de la herramienta de línea de comandos para notas del curso, en lugar de los archivos de tu proyecto de Timers (incluido notes.js). Tu trabajo anterior permanece en su propia lección. Lee los archivos proporcionados antes de editar store.js. Esta copia contiene los comandos para notas y funciones auxiliares asíncronas para archivos.

El almacén debería anunciar cada nota nueva y permitir que otro código decida qué hacer al respecto. Convierte el almacén en un emisor de eventos.

  1. En store.js, haz que store sea un EventEmitter que conserve todas sus propiedades y métodos. Importa EventEmitter desde node:events. new EventEmitter() crea un emisor nuevo y vacío. Copia el objeto del almacén en ese emisor con Object.assign, tal como muestra la lección.
  2. En store.js, dentro de add, después de guardar las notas, emite un evento added con dos valores: el texto de la nota y su número.
  3. En notes.js, escucha el evento added del almacén. El oyente imprime Saved note , el número y un punto. Añádelo cerca del principio, antes de que se ejecuten los comandos, para que ya esté escuchando cuando add emita el evento. La rama add ya no imprime nada; solo llama a store.add.

node notes.js add Buy bread imprime una línea con el número de la nota nueva, por ejemplo:

Saved note 3.

Después de clear, add Buy milk imprime Saved note 1., y add Call Ada imprime Saved note 2..

Pruébalo: escribe add Buy bread en el cuadro después de $ node notes.js y pulsa Intro. Verás Saved note y el número nuevo, impresos por tu oyente. Después, escribe clear, add Buy milk y add Call Ada: verás Saved note 1. y luego Saved note 2..

Pruébalo tú mismo

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 iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Conceptos básicos de Node.js

Practica por tu cuenta: Playground de Express