Páginas

sábado, 28 de noviembre de 2020

JavaScript: Ejemplo de asincronía, callbacks y promises

 Un ejemplo de código asíncrono es:

este código añade al array inicial tres números, el 4, el 5 y el 6. Estos números se añaden en un orden desconocido, el motivo es que la función addToArray hace uso de la función de javascript setTimeout. Esta función ejecuta el array.push después de un tiempo. En el caso del ejemplo el tiempo es elegido al azar por Math.random(). El resultado es que los elementos 4, 5 y 6 no se conoce de antemano en que orden apareceran. A cada ejecución el orden variará: [1, 2, 3, 5, 4, 6] o [1, 2, 3, 6, 4, 5] o cualquier otra combinación.

Utilizando callbacks esto se puede conseguir que los elementos se añadan en orden creciente siendo el resultado siempre [1, 2, 3, 4, 5, 6]. Esto se consigue con:

en este caso aunque addToArray sigue añadiendo los elementos en un tiempo indeterminado, se consigue que 4, 5 y 6 se añadan en el mismo orden siempre. Aquí la llamada a añadir el siguiente número es un callback del número anterior. Esto debido al funcionamiento interno de javascript que gestiona el orden en que se ejecutan las funciones con el stack queue y el callback queue hace que hasta que no se acaba de añadir el 4, no se añada el 5 y hasta que se acaba de añadir el 5 no se añada el 6. La importancia de esta técnica es conseguir sicronía cuando se necesita. Por ejemplo no mostrar una lista desplegable, mientras no tenemos disponibles los datos.

La técnica de callback, pronto se observó que conduce a un código no "limpio" (callback hell). Para evitar esto se ha incluido en javascript un objeto llamado Promise. Este objeto gestiona la asincronía. El ejemplo con Promise queda:

El método then del objeto promise hace que no se ejecute una función hasta que no haya terminado la anterior. Importante hacer notar que la función a controlar, en este caso addToArray debe devolver un objeto Promise para poder utilizar el método then.

Espero que este sencillo ejemplo le pueda ayudar a algún abnegado desarrollador para entender como funcionan las técnicas para manejar la asincronía intrinseca de javascript. 

Queda pendiente async-await para otro post.





jueves, 15 de octubre de 2020

JavaScript: Ejemplo de Closure

Ejemplo

Definición

Se produce una Closure cuando una función es capaz de recordar y acceder a su lexical scope mientras se ejecuta fuera de él.

Explicación

En este ejemplo a la variable externa se le asigna la función inicial(). Esta función declara dentro de su scope las variables var1 y var2.
 
Cuando en la última línea de código se ejecuta externa(), realmente la función que se está ejecutando es interna() que es el retorno de ejecutar inicial() en la sentencia let externa = inicial();. Esta  función interna() al ejecutarse hace uso de variables que están definidas e inicializadas en el scope de inicial() , pero se está ejecutando desde fuera del scope de inicial(). Esto es la closure.

Conclusión

Gracias a las closures, hay variables que pueden se usadas fuera de su scope. Eso sí, protegidas y manejadas por las funciones dentro de las que están declaradas. 

Bibliografía

'You Don't Know JS: Scope & Closures' de Kyle Simpson publicado por 'Reilly Media, Inc en Marzo 2014

domingo, 11 de octubre de 2020

JavaScript: Ejemplo de expresiones regulares.

Esto es una ayuda para quien tenga que construir una expresión regular y no sepa como hacerlo.
Los ejemplos están desarrollados con el método test de regexp. El método "test" devuelve true cuando hay coincidencia del patrón dentro de la cadena analizada y false cuando no.
Los ejemplos tienen la estructura:

    let patr = /patron/;  
    console.log (Descripción prueba, patr.test(cadena a analizar));

Ejemplos 


 

 

 

domingo, 4 de octubre de 2020

JavaScript: Ejemplo de función usada como parámetro (callback).

Las funciones son ciudadanos de primera clase en Javascript. Cuando se dice primera clase, es porque las funciones se tratan como cualquier otro tipo, ya sea primitivo o resultado de instanciar una clase creada por el desarrollador. Es decir, una función se puede utilizar igual que los otros tipos,  almacenándola en una array, utilizándola como parámetro de otra función, almacenándola  en una variable, etc.

Se muestra a continuación un ejemplo que hace uso de una función como parámetro de otra. Este ejemplo se muestra la misma funcionalidad codificada con 3 sintaxis distintas:
  •     funciones clásicas
  •     funciones anónimas
  •     funciones arrow
El objetivo es hacer los ejemplos comprensibles para el mayor número de programadores posible, independientemente del tipo de funciones que estén acostumbrados a manejar.

Funciones clásicas

Funciones anónimas

Funciones arrow

Estos tres códigos son equivalentes, es decir si los ejecutamos obtenemos el mismo resultado:

    Hi pepe suarez
    Bye pepe suarez

Las funciones conocidas como callback, son funciones que se pasan como parámetros a otras funciones y que se ejecutan dentro de éstas. Es decir el ejemplo tiene  dos funciones hi y bye que son llamadas como callbacks desde la función greeting.

Esta posibilidad de llamar a funciones desde otras funciones que las han recibido como parámetros, acerca a javascript hacia la programación funcional. La programación funcional permite desarrollar código más estable, porque está menos acoplado y es más legible frente a la programación imperativa.
 
Si se supone que no se puede utilizar funciones como parámetros. Una posible codificación para conseguir una funcionalidad igual a la mostrada podría ser:
 
Este código tiene estructura de programación imperativa. 
 
Supongamos que es necesario incluir un nuevo tipo de saludo por ejemplo “Buenas tardes”. ¿Qué cambios hay que realizar en cada caso serían:
  • En el primer caso “tipo funcional” tendríamos que añadir la función goodEvening(name, lastName) y llamarla desde greetings(goodEvening). Ningún cambio más es necesrio.
  • En el segundo caso “tipo imperativo” tendríamos que añadir la función goodEvening(name, lastName), un  nuevo tipo de saludo greeting(“goodEveningType”) y modificar la función greeting para que el if considerase que pueden existir un nuevo tipo de saludo.

Conclusión.

La posibilidad de utilizar funciones como parámetros, en este caso, permite generar un código más orientado a la extensión que a la modificación. Esto es debido a que en el caso “tipo funcional” extendemos el comportamiento del sistema sin la necesidad de cambiar nada en la función greeting. La modificación es más costosa en el caso “tipo imperativo” incluye tener que modificar la propia función greeting.
 

miércoles, 19 de agosto de 2020

Ejemplo de prueba de React con Jest

Para realizar pruebas automatizadas de las aplicaciones escritas con javascript es posible utilizar Jest. Jest tiene entre otras , una librería específica para probar componentes de React.

Aquí se describe una app realizada con React. Esta App tiene un único componente que dispone de una prueba automatizada realizada con Jest.

El código se puede descargar en https://github.com/MarisaAfuera/app-react-with-test 

Pasos seguidos para la realizar el ejemplo

1. Crear la app React con el comando ´npx create-react-app app-react-with-test`

2. Modificar el fichero app.js para que haga uso del componente CheckboxWithLabel.js. El fichero app.js queda con el siguiente contenido:

3. Copiar el componente CheckboxWithLabel.js y su fichero de prueba CheckboxWithLabel.Test.js que están en https://jestjs.io/docs/en/tutorial-react. El fichero de prueba se almacena en el directorio /tests, para aislar las pruebas de los fuentes de la aplicación. 

4. Se crea el fichero jest.config.js para indicar a Jest donde están los ficheros de prueba. Para que Jest utilice este fichero de configuración se modifica package.json, indicando donde está el fichero de configuración cuando se ejecute el script test.

4. Añadir la librería react-test-renderer para renderizar instantaneas de React con el comando: ´yarn add --dev react-test-renderer´

5.  Para eliminar el error `Jest encountered an unexpected token`

    5.1 Instalar `npm install --save-dev @babel/preset-react`

    5.2 Crear el fichero .babelrc con el contenido

    5.3 Instalar el módulo ´transform-es2015-modules-comonjs´ con el comando ´npm install --save-dev babel-plugin-transform-es2015-modules-commonjs´     

Terminando

Esto es todo.  Las versiones de las librerías utilizadas se pueden consultar en el archivo package.json de https://github.com/MarisaAfuera/app-react-with-test 

Espero que esto sirva de ayuda a algún programador.

 

   




martes, 4 de agosto de 2020

Ejemplo XmlHttpRequest

El ejemplo muestra como una página html hace mediante javascript una petición XMLHttpRequest para comprobar si existe o no un usuario en el servidor. El usuario se consulta en un API mediante punto de entrada. Por ejemplo: http://localhost:3000/users?name=Pedro para comprobar si en el servidor existe el usuario Pedro. En el caso de que exista se muestra un mensaje "Valid User Id" y en caso de que no exista se muestra "Invalid User Id".

La petición al API se envía mediante XmlHttpRequest de forma asincrona y cuando se recibe la respuesta se refresca solo el mensaje en la página, no la página completa.


pagina.html

onClick del botón Validar utiliza la función "validateUserId()" que hace una llamada asincrona al servidor. Tiene además un "return false" para que al hacer click no se refresque la página html completa, solo se refresca el mensaje con la función "setMessageUsingDOM(message)".

ejemploXHR.js

Este fichero contiene las funciones que crean y hacen uso de un objeto XmlHttpRequest para solicitar datos del servidor. Para ello:


1. Define una variable global.


2. Funciones validateUserID() y ajaxFunction(). Crean el objeto de tipo XmlHttpRequest, lo configuran y hacen la petición al servidor.

3. Función processRequest(). Esta función se ejecuta cada vez que el objeto XMLHttpRequest cambia de estado. Cuando alcanza el estado 4, la petición ha sido respondida desde el servidor.

4. Función setMessageUsingDOM(message). Muestra un mensaje en la pantalla dependiendo del valor de "message". True el usuario existe, false no existe.


db.json

Este componente contiene los usuarios que existen en el servidor. El servidor se ha suplantado(mockeado) con json-server. Para instalarlo ejecutar el comando "npm install -g json-server". Para arrancar el servidor ejecutar el comando "json-server --watch db.json". Si todo ha ido bien ya se puede abrir en el navegador "http://localhost:3000/users" y se verán los usuarios existentes.


Todo listo

Llegados aquí se puede abrir pagina.html en el navegador y probar la página html. Si quieres obtener el código completo https://github.com/MarisaAfuera/XmlHttpRequest.