Una sinfonía en C#

Un pequeño aporte a la comunidad de habla hispana.

Tips de Javascript: para qué sirve setTimeout = 0?

Tal vez hayan visto este código:

setTimeout(function(){
 //hacer ago
}, 0);

Básicamente es un timeout (es decir, esperar un tiempo y llamar al callback) con el tiempo en 0. Uno pensaría que esto se debe ejecutar inmediatamente, pero no es así, de hecho, el tiempo que puede tardar en teoría podría ser infinito, veámos un ejemplo:

console.log( +new Date );
	
setTimeout(function(){
	console.log( + new Date );	
		console.log("timeout");
}, 0);

image

Este pequeño código escribe los milisegundos y nos permite ver cuánto tardó la ejecución.

Digamos que es casi inmediato, en este caso tardó unos 21 ms en ejecutarse. Veamos el siguiente ejemplo.

console.log( +new Date );

setTimeout(function(){
	console.log( + new Date );	
	console.log("timeout");
}, 0);


for(var i = 0; i< 1000; i++){
	console.log("");
}

image

Esta vez agregamos un loop después del setTimeout y ahora tardó casi 200ms, si miramos con atención vemos que en realidad el código del callback se ejecutó recién después de que terminó de ejecutarse el loop, nada hace pensar que esto debería pasar, un pensaría que el tiempo debería ser similar al anterior y encontrarnos con el mensaje en medio de la ejecución del loop, pero no es así.

El call stack de Javascript

Javascript es single thread, es decir, hace una única cosa a la vez, lo que hace es poner las tareas en una pila de llamadas (el famoso stack overflow ocurre cuando sobrepasamos su límite) y las va ejecutando de a una.

En el caso de los timer (y otras cosas), lo que ocurre es que se colocan en el call stack (1) y luego se llama a las funciones especiales conocida como Web Apis (2) (son funciones especiales del navegador, en este caso cuentan el tiempo).

Luego que el intervalo se cumplió se colocan en el call queue indefinidamente (3) hasta que el call stack se encuentre vacío, entonces se pasa la función callback (en nuestro caso console.log(-new Date) ) al call stack y se ejecuta (4).

image

En nuestro ejemplo Javascript puso primero en el call stack nuestro setTimeout y detectó la llamada a funciones de Web Apis, luego de transcurrido el tiempo (0 ms) puso el callback en call queue; cuando el call stack quedó vacío (terminó de ejecutarse el bucle for) lo puso en call stack y lo ejecutó.

Es decir que: usar setTimeout con el interval en 0 es equivalente a decir “ejecutá esto cuando no haya nada más por ejecutar” y eso puede ser ya, o dentro de un tiempo mayor.

Nos leemos.

Introducción a Grunt: Javascript task runner

 

Hay tres palabras que siempre hay que tener presentes: automatizar, automatizar y automatizar. Toda tarea repetitiva y más aún si la misma nos aleja de nuestra tarea real, es importante encontrar la forma de automatizarla.

Automatizar para ser feliz

Para evitar errores, para evitar hacer cosas repetitivas (aburridas) y para mejorar nuestro proceso de desarrollo, recordemos: automatizar, automatizar y automatizar.

Grunt, el task runner para Javascript.

Hay algunas tareas que casi simpre vamos hacer cuando desarrollemos una aplicación en Javascript:

  • Minificar
  • Correr pruebas
  • Ejecutar inspección de código
  • Generar un paquete
  • Comprimir
  • Compilar

Cualquiera de estas tareas se pueden hacer con Grunt, que básicamente es eso: un ejecutor de tareas, como Ant o como MSBuild, pero para Javascript.

¿Qué necesito instalar?

Antes que nada NodeJs, una vez instalado NodeJs con npm instalamos grunt.

npm install -g grunt-cli

Y listo, ya lo tenemos instalado

Ejemplo simple: minificar.

Típicamente un proyecto con Grunt va a tener dos archivos de configuración

package.json

gruntfile.json

El primero indica las dependencias (por ejemplo los paquetes externos que utilizaremos para nuestras tareas) el segundo la configuración de las tareas.

Un ejemplo del package.json para poder utilizar el paquete de minificación es éste:

{
  "name": "prueba",
  "version": "0.1.0"
}

Vemos que no dice mucho más que el nombre del proyecto y la versión pero dijimos que necesitamos indicar las dependencias, bien, podemos agregarlas a mano o podemos hacer que npm lo haga por nosotros del siguiente modo:

npm install grunt grunt-contrib-uglify --save-dev

En este caso decimos que instale grunt y grunt-contrib-uglify y con –-save indicamos que guarde la configuración en nuestro package.json con dev es decir, que es algo para desarrollo no es necesario para correr el proyecto. Entonces nuestro archivo queda así:

{
  "name": "prueba",
  "version": "0.1.0",
  "devDependencies": {
    "grunt": "^0.4.5",
    "grunt-contrib-uglify": "^0.6.0"
  }
}

Perfecto, cuando alguien necesite correr la aplicación hace npm install y todo se instale automáticamente.

Ahora si, vamos a configurar grunt dentro de gruntfile.js.

module.exports = function (grunt) {
	//configuración de grunt
	grunt.initConfig({
		uglify : { 		//nombre de la tarea, uglify
			build : { 	//nombre de la configuración, es un nombre arbitrario
				src : 'js/*.js',		//archivos origen
				dest : 'package/code.min.js'	//archivo destino
			}
		}
	});
	grunt.loadNpmTasks('grunt-contrib-uglify'); //cargamos el módulo que contiene uglify
};

Como vemos en la descripción del código lo que hacemos es indicar a través del método initConfig nuestra configuración.

uglify es el nombre de la tarea que deseamos correr (la que instalamos con npm antes) y dentro de la misma podemos tener más de una configuración (por ejemplo test, ci, production) en este caso le puse build. Los parámetros src y dest indican qué queremos minificar esto está en la documentación de la tarea

Vamos a la consola y ejecutamos grunt

image

Error. Lo que pasa es que ya que podemos tener muchas tareas tenemos que indicar cuál queremos correr, esto lo podemos hacer así:

grunt uglify

Por supuesto que si no queremos hacer esto cada vez podemos indicar cuál es la tarea por defecto dentro de la configuración

module.exports = function (grunt) {
	//configuración de grunt
	grunt.initConfig({

		uglify : { 		//nombre de la tarea, uglify
			build : { 	//nombre de la configuración, es un nombre arbitrario
				src : 'js/*.js',		//archivos origen
				dest : 'package/code.min.js'	//archivo destino
			}
		}
	});

	grunt.loadNpmTasks('grunt-contrib-uglify'); //cargamos el módulo que contiene uglify
	grunt.registerTask('default', ['uglify']); //tarea por defecto
};

Ahora hacemos simplemente

grunt

y listo

image

Obtenemos un archivo minificado con el contenido de todos los .js que estaban en el directorio “js”.

Nos leemos en la próxima.

Javascript Hoisting, scope de variables

Una característica de Javascript difícil de comprender (sobre todo comprender si es un bug o un feature) es el scope de las variables declaradas dentro de una función.

El intérprete de Javascript mueve las declaraciones al principio de la función.

Esto quiere decir que si yo declaro una variable por la mitad del código de una función su declaración (no la asignación) se mueve al principio, veamos un ejemplo:

var a = 'hola';

function saludar() {
	console.log(a);
	var a = 'chau';
	console.log(a);
};

saludar();

image

En este caso esperamos que le primer mensaje en imprimirse diga “hola” sin embargo dice “undefined” ¿por qué? simple: para el interprete la declaración está al principio de la función, es decir, que lo que en realidad se ejecuta es esto:

var a = 'hola';

function saludar() {
	var a;
	console.log(a);
	a = 'chau';
	console.log(a);
};

saludar();

En definitiva lo importante es tener en cuenta este comportamiento o poner todas las declaraciones al principio.

Nos leemos. Leonardo.

Taller sobre AngularJs en Buenos Aires

Este jueves 6 de Noviembre voy a estar una vez más en las instalación del Microsoft User Group en Buenos Aires, esta vez con un taller sobre AngularJs.

Ejemplos prácticos

El taller se desarrollará a través de 50 ejemplos prácticos, los mismo quedarán publicados en Github.

Le idea es ir avanzando paso a paso con ejemplos para que una vez terminados los dos encuentros tener las herramientas básicas para empezar a trabjar con Angular.

Dejo el link con la información para anotarse. Nos vemos!

Taller en Buenos Aires: Desarrollo ágil con JavaScript. Prácticas, técnicas y herramientas.

El próximo Jueves 5 de Junio estaré en la ciudad de Buenos Aires dando un taller todo el día sobre desarrollo de aplicaciones en un ambiente ágil utilizando JavaScript.

La motivación

Después de leer un interesante post del Tío Bob sobre “La verdadera corrupción de la agilidad” y sumado a esto este hilo en la lista de Ágiles pensé en qué herramientas, prácticas y técnicas del día a día me ayudan a mí en el desarrollo ágil, cómo las adoptamos en el equipo, qué ventajas encontramos, qué limitaciones, cómo se combinan entre ellas y con las metodologías como Scrum, o Kamban.

¿Quiénes puden participar?

Idealmente programadores con conocimientos de JavaScript o que participen en equipo que trabajen con alguna metodología ágil.

¿De qué vamos a hablar?

  • Agilidad, Scrum, XP, Kamban, etc.
  • TDD, Pair programming.
  • UI Test
  • SOLID.
  • Automatización
  • Herramientas como templating, MVC, modularización
  • Git, cómo nos ayuda a gestionar los cambios
  • Más sobre automatización.

¿Por qué JavaScript?

Los últimos dos años trabajé prácticamente todo el tiempo con JavaScript y es un lenguaje cómodo para muchas cosas por su naturaleza dinámica, además no se necesita un entorno particular para ejecutarlo.

¿A qué apuntamos?

La idea es repasar cómo estás técnicas, herramientas y prácticas nos ayudan a soportar los procesos de desarrollo ágil, cuáles son los puntos claves, cuáles los problemas y cómo las adoptamos.

¿Vamos a hacer algo con la máquina?

Sí, vamos a hacer algunos pequeños ejemplos de las herramientas más interesantes.

¿Qué herramientas?

  • Qunit
  • Requirejs
  • Bower
  • r.js
  • Backbonejs
  • Git
  • Rivetsjs
  • underscorejs
  • jquery
  • blanket
  • Phantom

Intentaremos introducir algunas de ellas utilizando Pair programing, Pomodoro technique y TDD.

Ah, y sobre todo vamos a hablar mucho de automatización, automatización, automatización, etc. Guiño

¿Qué queremos llevarnos?

  • Intercambiar opiniones, experiencias y puntos de vista sobre el desarrollo ágil
  • Conocer algunas herramientas que tal vez hayamos escuchado nombrar, sus ventajas, sus limitaciones.
  • Compartir experiencias haciendo desarrollo ágil.
  • Entender cómo nos ayudan las técnicas y herramientas a trabajar de manera ágil.

Entonces la cita está hecha, será el próximo jueves 5 de Junio de 9:30hs a 17:45 en el Microsoft User Group en Buenos Aires Argentina, dejo el link para anotarse en la charla, nos leemos.