Características destacables de NodeJS

  • Por
  • y  
Para definir Node.JS mejor viene bien observar algunas características de la plataforma y las diferencias de NodeJS con Javascript común y con otros lenguajes de programación.

Este Manual de Node.JS está creado a través de unas charlas #nodeIO que hemos realizado en DesarrolloWeb.com, de las cuales estos artículos son una transcripción. En este punto estamos todavía en la primera charla, en la que Alejandro Morales nos está aclarando algunos conceptos importantes para poder entender bien qué es NodeJS.

En el artículo anterior vimos cómo se instalaba esta NodeJS y en el presente texto veremos en detalle algunas de las características más fundamentales de NodeJS. Entre todas ellas nuestro ponente Alejandro Morales destacó: JavaScript sin limitaciones, Programación asíncrona y Programación orientada a eventos. Todos estos puntos los veremos a continuación.

Un Javascript "sin restricciones"

Con NodeJS tenemos un "Javascript sin restricciones", tal como afirma @_alejandromg, ya que todo se ejecuta en el servidor y no tenemos que preocuparnos de si nuestro código será compatible o no con distintos clientes. Todo lo que escribas en Node JS y te funcione en tu servidor, estarás seguro que funcionará bien, sea cual sea el sistema que se conecte, porque toda la ejecución de código del servidor se queda aislada en el servidor.

Nota: Este detalle de fiabilidad y compatibilidad, o lo que ha llamado el autor como Javascript "sin restricciones" (por estar ejecutado en un ambiente seguro, del lado del servidor) no deja de ser una ventaja de todos los lenguajes del lado del servidor, como PHP, ASP.NET, JSP, etc.

Pero no sólo eso, el Javascript original tiene algunas estructuras de control que realmente no se utilizan en el día a día, pero que realmente existen y están disponibles en NodeJS. En algunas ocasiones resulta especialmente útil alguna de las mejoras de Javascript en temas como la herencia.

Otro ejemplo es que en Javascript haces:

for(var key in obj){ }

Mientras que en las nuevas versiones de Javascript podrías hacer esto otro:

Object.keys(obj).forEach()

Programación Asíncrona

Éste es un concepto que algunas personas no consiguen entender a la primera y que ahora toma especial importancia, dado que NodeJS fue pensado desde el primer momento para potenciar los beneficios de la programación asíncrona.

Imaginemos que un programa tiene un fragmento de código que tarda cinco segundos en resolverse. En la mayoría de los lenguajes de programación precedentes, durante todo ese tiempo el hilo de ejecución se encuentra ocupado, esperando a que pasen esos cinco segundos, o los que sea, antes de continuar con las siguientes instrucciones. En la programación asíncrona eres capaz de liberar el proceso de modo que los recursos se quedan disponibles para hacer otras cosas durante el tiempo de espera.

Un ejemplo claro de esto es una llamada a un servicio web, o una consulta a la base de datos. Una vez realizada la solicitud generalmente pasará un tiempo hasta que se obtenga la respuesta. Ese tiempo, por corto que sea, dejaría un proceso esperando en la programación tradicional y en la asíncrona simplemente se libera. En NodeJS, o en Javascript en general, cuando esa espera ha terminado y se ha recibido la respuesta, se retomará la ejecución del código. Para definir las acciones a realizar (código a ejecutar) cuando se haya terminado esa espera, se especifica el código mediante funciones llamadas habitualmente "callbacks". Esas funciones contendrán las líneas de código que ejecutar al final de esos procesos de espera, y una vez se ha recibido la respuesta.

La filosofía detrás de Node.JS es hacer programas que no bloqueen la línea de ejecución de código con respecto a entradas y salidas, de modo que los ciclos de procesamiento se queden disponibles durante la espera. Por eso todas las APIs de NodeJS usan callbacks de manera intensiva para definir las acciones a ejecutar después de cada operación I/O, que se procesan cuando las entradas o salidas se han completado.

Nota: Estos callbacks probablemente ya los hayas usado un montón de veces si tienes experiencia con Javascript del lado del cliente, porque se usan en funciones muy habituales como setTimeout(), que también está disponible en NodeJS. Librerías Javascript como jQuery también las usan de manera intensiva.

Por ejemplo miremos este código:

console.log("hola");
fs.readFile("x.txt", function(error, archivo){
   console.log("archivo");
})
console.log("ya!");

Realmente Javascript es primeramente síncrono y ejecuta las líneas de código una detrás de otra. Por ese motivo, como resultado de ejecución del código anterior, primero veremos el mensaje "hola" en la consola, luego el mensaje "ya!" y por último, cuando el fichero terminó su lectura, veremos el mensaje "archivo".

Por la forma de ejecutarse el código se puede entender la programación asíncrona. La segunda instrucción (que hace la lectura del archivo) tarda un rato en ejecutarse y en ella indicamos además una función con un console.log ("archivo"), esa es la función callback que se ejecutará solamente cuando termine la lectura del archivo. Por ese detalle, lo último que aparecerá en pantalla es el contenido del fichero. Este detalle es de extrema importancia para entender la programación con NodeJS.

Problema del código piramidal

El uso intensivo de callbacks en la programación asíncrona produce el poco deseable efecto de código piramidal, también conocido habitualmente como "código Espagueti" o "callback hell". Al utilizarse los callbacks, se meten unas funciones dentro de otras y se va entrando en niveles de profundidad que hacen un código menos sencillo de entender visualmente y, por tanto de mantener durante la vida de las aplicaciones.

La solución es hacer un esfuerzo adicional por estructurar nuestro código. Básicamente se trata de modularizar el código, escribiendo cada función aparte e indicando solamente su nombre cuando se define el callback. Podrías incluso definir las funciones en archivos aparte y requiriéndolas con require("./ruta/al/archivo") en el código de tu aplicación. Todo esto lo veremos con detalle en numerosos ejemplos en el Manual de NodeJS, por lo que no te debes de preocupar mucho si todavía no lo entiendes.

Al conseguir niveles de indentación menos profundos estamos ordenando el código, con lo que será más sencillo de entender y también más fácil de encontrar posibles errores. Además, a la larga conseguirás que sea más escalable y puedas extenderlo en el futuro o mantenerlo por cualquier cuestión.

Nota: También en ES6 existen otras herramientas como las promesas que te ayudan a mantener tu código ordenado con la programación asíncrona y el uso de callbacks

Algunos consejos a la hora de escribir código para que éste sea de mayor calidad:

  • Escribe código modularizado (un archivo con más de 500 líneas de código puede que esté mal planteado)
  • No abuses, no repitas las mismas cosas, mejor reusa.
  • Usa librerías que ayuden al control cuando lo veas necesario (como async que te ayuda a ordenar ese montón de callbacks)
  • Usa promesas y futuros
  • Conoce el lenguaje y mantente al día con las novedades de las presentes y futuras versiones de Javascript ES6, ES7...

Programación orientada a eventos (POE)

Conocemos la programación orientada a eventos porque la hemos utilizado en Javascript para escribir aplicaciones del lado del cliente. Estamos acostumbrados al sistema, que en NodeJS es algo distinto, aunque sigue el mismo concepto.

En Javascript del lado del cliente tenemos objetos como "window" o "document" pero en Node.JS no existen, pues estamos en el lado del servidor.

Eventos que podremos captar en el servidor serán diferentes, como "uncaughtError", que se produce cuando se encuentra un error por el cual un proceso ya no pueda continuar. El evento "data" es cuando vienen datos por un stream. El evento "request" sobre un servidor también se puede detectar y ejecutar cosas cuando se produzca ese evento.

Volvemos a insistir, NodeJS sería un equivalente a PHP, JSP, ASP.NET y entonces todo lo que sean eventos de Node, serán cosas que ocurran en el lado del servidor, en diferencia con los eventos de Javascript común que son del lado del cliente y ocurren en el navegador.

Nota: La comparación de Node.JS con lenguajes del lado del servidor viene bien para entender cómo pueden sus eventos ser distintos que los de Javascript del lado del cliente. Sin embargo debemos saber que que Node.JS es más bien una plataforma basada en Javascript. NodeJS viene con muchas utilidades para programación de propósito general y para realizar programas que implementarían servidores en sí mismos, por lo que su equivalente más próximo podría ser algo como Django o Ruby on Rails. Aunque habría que matizar que esa comparación puede ser un poco atrevida, debido que NodeJS estaría en un nivel mucho más bajo (más cercano a la máquina) y aunque lo podrías usar sin más añadidos para el desarrollo de sitios web, se combina con otros frameworks como ExpressJS para dar mayores facilidades para la creación de sitios aplicaciones web.

Conclusión

Poco a poco vamos entendiendo qué es (y que NO es) NodeJS. Son todo conceptos que resultarán nuevos para muchos de los lectores y por ello era importante dejarlos claros. Ahora vamos a pasar a explicar algunas otras cosas de interés que utilizamos en el día a día en esta plataforma, como el gestor de paquetes npm.

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Autor

Alejandro Morales Gámez

Alejandro Morales es un desarrollador web, especialista en JavaScript, Node.js, lua y Ruby. Gran aficionado de los proyectos de código abierto (Open Source), con más de 50 contribuciones a diferentes proyectos, entre los cuales esta: Nodester y npmjs.org... Autor de más de 6 módulos para node.js. Escritor ocasional. Gran observador de la conducta humana y uno de los fundadores de numbus.co.
Desarrollador web, especialista en JavaScript, Node.js, lua y Ruby.

Compartir

Comentarios

hardsome

24/1/2013
DUDA
Muy interesante el articulo, pero, me quedó una duda no entiendo bien a que se refiere cuando dice "Usa un estilo continuable" al momentode escribir el código.

AlbertFM

16/2/2013
RE: hardsom...
@hardsom... yo creo que se refiere a seguir un codigo evolutivo u ordenado. Para explicarme mejor te pongo un ejemplo:
El siguiente código es valido pero no es continuado:
segundo;
function segundo() {
primero;
console.log('Segundo ejecutado');
};
function primero() {
console.log('Primero ejecutado');
};

Esto sería el mismo código continuado (mas fácil de entender):
function primero() {
console.log('Primero ejecutado');
};
function segundo() {
primero;
console.log('Segundo ejecutado');
};
segundo;

Ambos sacarían la misma salida:
>Primero ejecutado
>Segundo ejecutado

Alejandro Morales

18/3/2013
Estilo continuable
Hola, disculpas por responder tarde, el estilo continuable se refiere a utilizar "function calls" en vez de parametros, como has de entender el callback es un parametro cuando llamas el método, el estilo continuable te regresa una función de ejecución para iniciar el proceso o llamada async.

Un ejemplo de implementación y uso lo puedes ver aquí: https://gist.github.com/alejandro/4192304

Antonio Morales

30/1/2015
No entiendo una cosa
Si se se dice que Node tiene un único hilo de ejecución, ¿cómo se concibe que sea a su vez asíncrono?, si precisamente la definición de asíncrono es que se generan varios hilos.

armandormg@gmail.com

22/5/2015
Porque usar node.js??
Si node.js es equivalente a php o asp, porque habría de utilizarlo?, cuando puedo utilizar php con symfony por ejemplo, o asp, con todas las ventajas de .net.