node (7): process

Introducción al objeto global process

Shozo Shimamoto

archivado en: JavaScript / 17 septiembre, 2016 / taller:

Cada vez que se ejecuta una aplicación node comienza un proceso que podemos controlar mediante el objeto global process (y al ser global no hace falta importarlo con require para que esté accesible desde cualquier lugar). Salvando las distancias, para entender el papel que desempeña podemos equipararlo al objeto window de las páginas web.

Entre sus propiedades destacan:

  • process.execPath: la ruta donde se está ejecutando el programa (ie,  c:\Program Files\nodejs\node.exe).
  • process.env: un objeto con una montonera de información sobre la configuración de la máquina donde se está ejecutando el programa, como PATH, que tiene todas las variables de entorno.
  • process.versions: un objeto con información sobre la versión de node, el motor v8, etcétera.
  • process.config: otro objeto, esta vez con la configuración de node (ie, si estamos en modo harmony).
  • process.platform: un string con el SO (ie, win32).
  • process.pid: de forma automática, node asigna un id a cada proceso, cuyo valor se guarda en esta propiedad.
  • process.argv: un array con los argumentos que le hemos pasado al ejecutar el programa.

Hay varias más, pero solo me detendré en otras dos: stdout y  stdin, que nos permiten trabajar con streams asociados a process. Stdin es un stream de lectura (readable) y stdout de escritura. Por ejemplo, así abriríamos un stream de lectura para capturar todo lo que se escribe por consola y repetirlo mediante el stream de lectura stdout.

process.stdin.setEncoding('utf8');

process.stdin.on('readable', () => {

let chunk = process.stdin.read();

if (chunk !== null) {

process.stdout.write(`has escrito: ${chunk}`);

}

});

Bueno, en realidad hay una manera más chula de hacer esto y como esta entrada puede ser un tostón enumerativo, voy a contarla ahora, aunque se salga un poco del tema tratado.

Readline

Para interactuar con un usuario mediante la consola, es decir, para recibir (in) y lanzar (out) mensajes, necesitamos las propiedades de process stdin y stdout, así como el módulo readline.

Para poder usar el módulo, una vez cargado con require(), hay que crear una interfaz, que cacheamos en una variable del tipo const (no va a setearse de nuevo), en la que definimos dos parámetros: uno para indicar cuál será la fuente de entrada, que será el stream stdin, y otro para la salida, el process.stdout.

Ale op, de esta forma tan sencilla, ya tenemos disponibles los distintos métodos de readline, como question(), que permite lanzar un mensaje y capturar la respuesta en una función callback.

const readline = require('readline');

const inout = readline.createInterface({

input: process.stdin,

output: process.stdout

});

inout.question('It\'s a wonderfull day?', (answer) => {

console.log(`Why u you say ${answer}?`);

});

Entonces, para ver cómo funciona, podemos preguntarle al usuario si algo es bueno, bonito y barato. En una variable iremos guardando el orden de las preguntas y en otra, las respuestas del usuario. Luego, iremos preguntando por orden mientras queden preguntas y, cuando terminemos, cerramos el proceso:

let questionsCount = 0;

let userResponses = [];

module.demoQuestion = ()=> {

const questions = [

'its good?',

'its nice?',

'its cheap?'

];

if ( questionsCount < 3 ) {

inout.question(questions[questionsCount], (userResponse) => {

userResponses.push(userResponse);

questionsCount++;

self.demoQuestion();

});

} else {

console.log('u think that is: ' , userResponses.join() );

process.exit(0);

}

};

Bueno, tras este excurso, volvemos a process.

Métodos y eventos

No voy a tratar todos los métodos de process, ya que sería un tostón para el lector y para mí, pero sí hay dos que debemos conocer bien

Uno es exit([código]), con el cual podemos poner fin a un proceso.

process.exit();

Este método acepta como argumento un código de salida. Los más habituales son:

1. Uncaught Fatal Exception

5. Fatal Error

9. Invalid Argument

También podemos detener un proceso en concreto con process.kill([idProceso]) indicando como parámetro su id.

El segundo método fundamental es nextTick([callback]), que equivaldría en cierta manera al $digest() o el $apply() de Angular 1.*, el cual podríamos traducir en aras de la didáctica como «aLaSiguienteVuelta()» y que sirve para retrasar la ejecución de un método.

Para comprender su utilidad, pensemos en esas situaciones donde definimos cosas antes de que estén listas. Por ejemplo, este snippet cascaría, ya que estamos invocando el método foo de miInstancia antes de haberla creado.

var Objeto = function() {

this.foo = ()=> {

console.log('Hey, soy foo');

};

}

miInstancia.foo(); // Chungo, miInstancia aún no existe.

miInstancia = new Objeto();

Sin embargo, de esta otra manera funcionaría, ya que le decimos a node que no ejecute ese método sino hasta la siguiente vuelta del loop, cuando miInstancia ya ha quedado definida.

var Objeto = function() {

this.foo = ()=> {

console.log('Hey, soy foo');

};

}

process.nextTick( ()=> {

miInstancia.foo();

});

miInstancia = new Objeto();

El objeto process también tiene eventos. Los más importantes son:

exit: cuando se detiene un proceso.

beforeExit: justo antes de que se detenga.

uncaughtException: cuando se produce un error que detiene el proceso:

process.on('uncaughtException', function (er) {

console.error('se lio parda: ' + er.stack);

process.exit();

});

throw new Error("Ay, ay, por aquí se rompió algo");

Además, también se pueden incluir listeners de «señales» (signals), un término que proviene del mundo Unix y que vendría a ser algo así como una notificación asíncrona de que ha sucedido determinado evento en un proceso. Por ejemplo, la señal SIGINT indica que ha terminado porque se ha pulsado la combinación de teclas ctrl+c, que detiene todo lo detenible por consola.

process.on('SIGINIT', ()=> {

console.log('Hasta luego!');

});

Bueno, se podrían contar muchas más cosas de process, pero espero que con esto baste como introducción para aterrizar en la documentación oficial.

|| Tags: , ,

Este artículo aún no ha sido valorado.

¿Te ha parecido útil o interesante esta entrada?
dormido, valoración 1 nadapensativo, valoración 2 un poco sonrisa, valoración 3 a medias guiño, valoración 4 bastante aplauso, valoración 5 mucho

Tú opinión es muy importante, gracias por compartirla!

Aportar un comentario


*