Node.js viene con una colección de módulos nativos para realizar tareas comunes sin necesidad de instalar dependencias adicionales. Algunos de los más utilizados son:
fs: Manipulación de archivosEl módulo fs permite trabajar con el sistema de archivos.
Ejemplo básico para leer y escribir archivos:
const fs = require('fs');
// Leer un archivo
fs.readFile('archivo.txt', 'utf8', (err, data) => {
if (err) {
console.error('Error al leer el archivo:', err);
return;
}
console.log('Contenido del archivo:', data);
});
// Escribir en un archivo
fs.writeFile('archivo.txt', 'Hola, Node.js!', (err) => {
if (err) {
console.error('Error al escribir en el archivo:', err);
return;
}
console.log('Archivo escrito correctamente.');
}); http: Crear un servidor HTTPCon el módulo http, puedes crear un servidor básico:
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hola, Mundo desde Node.js!');
});
server.listen(3000, () => {
console.log('Servidor ejecutándose en http://localhost:3000');
}); path: Manejo de rutasEl módulo path simplifica el manejo de rutas de archivos:
const path = require('path');
const rutaAbsoluta = path.resolve('archivo.txt');
console.log('Ruta absoluta:', rutaAbsoluta);
const nombreArchivo = path.basename(rutaAbsoluta);
console.log('Nombre del archivo:', nombreArchivo);
const extension = path.extname(rutaAbsoluta);
console.log('Extensión:', extension); events: Emisión de eventosEl módulo events facilita la creación y manejo de eventos personalizados:
const EventEmitter = require('events');
const emisor = new EventEmitter();
// Escuchar un evento
emisor.on('saludo', (nombre) => {
console.log(`¡Hola, ${nombre}!`);
});
// Emitir un evento
emisor.emit('saludo', 'Node.js'); stream: Lectura/escritura de flujos de datosLos flujos (streams) permiten trabajar con datos de manera eficiente.
Por ejemplo, para leer un archivo en partes:
const fs = require('fs');
const streamLectura = fs.createReadStream('archivo.txt', 'utf8');
streamLectura.on('data', (chunk) => {
console.log('Datos leídos:', chunk);
});
streamLectura.on('end', () => {
console.log('Lectura finalizada.');
}); Un callback es una función que se pasa como argumento a otra función y se ejecuta después de que la primera función termine.
Ejemplo básico:
function hacerAlgo(callback) {
console.log('Haciendo algo...');
callback();
}
hacerAlgo(() => {
console.log('Hecho!');
}); Callback Hell: Cuando los callbacks se anidan en varias capas para manejar flujos complejos, el código puede volverse difícil de leer y mantener. Esto se conoce como Callback Hell o la “pirámide de la perdición”.
obtenerDatos((error, datos) => {
if (error) {
console.error('Error al obtener datos:', error);
} else {
procesarDatos(datos, (error, resultado) => {
if (error) {
console.error('Error al procesar datos:', error);
} else {
guardarDatos(resultado, (error) => {
if (error) {
console.error('Error al guardar datos:', error);
} else {
console.log('Datos guardados correctamente');
}
});
}
});
}
}); Como puedes ver, múltiples niveles de callbacks anidados pueden hacer que el código sea más complejo y menos legible, dificultando su depuración y mantenimiento.
Callback HellPara evitar este problema, se pueden utilizar técnicas modernas como:
axiosLas promesas en JavaScript son una forma moderna y más limpia de manejar tareas asincrónicas, evitando el problema del Callback Hell. Permiten ejecutar código cuando una operación se completa correctamente (resolve) o cuando ocurre un error (reject).
function obtenerDatos() {
return new Promise((resolve, reject) => {
const exito = true; // Cambia esto a `false` para simular un error.
setTimeout(() => {
if (exito) {
resolve('Datos obtenidos correctamente');
} else {
reject('Error al obtener los datos');
}
}, 2000); // Simula una tarea asincrónica con setTimeout
});
}
obtenerDatos()
.then((resultado) => {
console.log(resultado); // 'Datos obtenidos correctamente'
})
.catch((error) => {
console.error(error); // 'Error al obtener los datos' (si exito es false)
}); async/awaitasync/await es una forma aún más sencilla y legible de manejar tareas asincrónicas en JavaScript, basada en Promesas.
Permite escribir código que parece síncrono mientras maneja operaciones asincrónicas.
// Función que simula obtener datos de manera asincrónica
function obtenerDatos() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Datos obtenidos correctamente');
}, 2000); // Simula un retraso de 2 segundos
});
}
// Función que usa async/await para esperar la respuesta
async function ejecutar() {
try {
console.log('Obteniendo datos...');
const resultado = await obtenerDatos(); // Espera a que la promesa se resuelva
console.log(resultado); // 'Datos obtenidos correctamente'
} catch (error) {
console.error('Error:', error); // Maneja errores
}
}
ejecutar(); async: Declara la función ejecutar como asincrónica, lo que permite usar await dentro de ella.await: Hace que la ejecución espere hasta que la promesa obtenerDatos se resuelva o rechace.try/catch: Captura y maneja errores que puedan ocurrir durante la operación asincrónica.