tag:blogger.com,1999:blog-8957305324514452802024-03-21T15:14:27.897-07:00Asuntos de SoftwareBlog creado por un desarrollador para desarrolladores. Me gusta compartir inquietudes y conocimientos. Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.comBlogger68125tag:blogger.com,1999:blog-895730532451445280.post-32192110276566825002023-09-25T09:56:00.002-07:002023-09-25T09:56:07.832-07:00Un ejemplo de Mock Service Worker con React <p>Cuando se trata de hacer una aplicación web muy a menudo se utiliza un API Rest que suministra datos desde el backend. No siempre está disponible el backend en el momento en que se empieza a desarrollar el frontend o incluso a veces es deseable no depender de los vaivenes del desarrollo del backend.</p>
<p>Para aislar al frontend del backend es útil la librería Mock Service Worker. Mediante esta librería podemos simular el backend cómo si ya estuviese disponible aunque no lo esté. Vamos a ver un ejemplo.</p>
<p>Para acceder a los recursos del backend se utilizan métodos HTTP. En este ejemplo vamos a simular un get que devuelve frases famosas. El get se simula con:</p>
<script src="https://gist.github.com/MarisaAfuera/05be6a56351a1c71cbc600ed698ca15a.js"></script>
<p>Es decir, cuando desde el frontend se ejecuta el fetch que envía el get, si estamos en el entorno de desarrollo se ejecuta un get que devuelve un fichero json con estas 2 citas. Para distinguir el entorno de desarrollo del de producción se usa una variable de entorno de la siguiente manera:</p>
<script src="https://gist.github.com/MarisaAfuera/81ae64d962689140a152f5909be8366a.js"></script>
<p>https://thesimpsonsquoteapi.glitch.me/" es la url del backend real, la que se utilizará en producción cuando todo esté funcionando.
</p>
<p>
Entonces lo que es necesario para que todo esto funciones es instalar la librería Mock Service Worker con <code>npm install msw --save-dev</code>
Y utilizar la función setupWorker con el workersetup.js con el siguiente contenido:
</p>
<script src="https://gist.github.com/MarisaAfuera/ac6f0a0b0ab2f81fa8cf698eb23d7a02.js"></script>
<p>Bueno pongo todo en orden para que se entienda:</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5K-yAo6da5HQVMT91sAPlpG_w6Xg8L79ZgqvCN8qUX4dYCdX1PS3Y3vbCjaLKfOamU0zwcEkBoEkOW9aH3kdLxDWoGLdB4hv1sbdaVApjci-lBMV_yGuYckwe7rK5HAfSFBJvywI0cEcF1H8raUm8301AnIeh8CCcjKDqUVnnpy2W8TKWkBsbrbQY25F7/s888/GraficoMockServiceWorker.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="369" data-original-width="888" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5K-yAo6da5HQVMT91sAPlpG_w6Xg8L79ZgqvCN8qUX4dYCdX1PS3Y3vbCjaLKfOamU0zwcEkBoEkOW9aH3kdLxDWoGLdB4hv1sbdaVApjci-lBMV_yGuYckwe7rK5HAfSFBJvywI0cEcF1H8raUm8301AnIeh8CCcjKDqUVnnpy2W8TKWkBsbrbQY25F7/s400/GraficoMockServiceWorker.png"/></a></div>
<p>
Main-page.js es un componente React que determina cual es la URL que se utilizará para el get como hemos visto anteriormente. El objetivo de este componente es mostrar todas las citas que devuelve el blackend. El contenido de Main-page.js es:
</p>
<script src="https://gist.github.com/MarisaAfuera/50a63f37f48e13b2b2a028d22f1574aa.js"></script>
<p>En este ejemplo cuando se está realizando la ejecución en el entorno de desarrollo el get se efectúa a /quotes y cuando es otro entorno, en este caso producción el get se efectúa a https://thesimpsonsquoteapi.glitch.me/quotes. Son workerSetup.js y handlers.js los que se encargan de simular la respuesta del get cuando la petición se lanza a /quotes.
</p>
<p>Entonces lo que vemos en la pantalla cuando ejecutamos este componente en el entorno de desarrollo es:</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsuuzCek5rsF7Nu8reFXBea4FzkrGKoM_FUEV7wtmA5ZBTdOS2KYvBPojh8uawVvEjJND3c_Onz_TJo0MjEx_ZZLOqLJDA5Ex3Aq0kfPPmETttyO0GF8DkVNSqkTLJrwwx-w3PMjqCUpty_Or00SdIFA4SXlpxjTn1M3VPsh8nZrBRHuVSfYxUFrfvYxy0/s670/PantallaEjecucion.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="367" data-original-width="670" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsuuzCek5rsF7Nu8reFXBea4FzkrGKoM_FUEV7wtmA5ZBTdOS2KYvBPojh8uawVvEjJND3c_Onz_TJo0MjEx_ZZLOqLJDA5Ex3Aq0kfPPmETttyO0GF8DkVNSqkTLJrwwx-w3PMjqCUpty_Or00SdIFA4SXlpxjTn1M3VPsh8nZrBRHuVSfYxUFrfvYxy0/s400/PantallaEjecucion.png"/></a></div>
<p>Coincidiendo las citas que se muestran en pantalla con las que se crean en el objeto handlers.js cuyo contenido se mostró en la primera imagen de código.</p>
<h2>Conclusión</h2>
<p>Esta librería nos puede ayudar cuando durante el desarrollo queremos independizar el frontend del backend. Es decir podemos ir avanzando el frontend aunque el backend no esté disponible.</p>
Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-73651343151072638952023-08-12T03:15:00.002-07:002023-08-12T03:15:36.478-07:00Un ejemplo de Cucumber para hacer BDD (Behavior driven development)<p>
BDD tiende un puente para que los expertos del negocio y los informáticos se entiendan sin fisuras. BDD alienta la colaboración, construye compresión compartida sobre el comportamiento esperado del sistema, produce documentación que guía el desarrollo y permite validar el comportamiento del sistema de forma automática.
</p>
<p>
Trabajando en rápidos y pequeños ciclos mejora la retroalimentación y el flujo de valor. Hacer BDD es hacer tres cosas una y otra vez: se toma una pequeña funcionalidad y se conversa sobre los detalles de cómo se espera que el sistema se comporte usando ejemplos concretos, luego se documentan esos ejemplos en una forma en la cual se pueden automatizar y se corrobora que hay acuerdo, para terminar se codifica con lenguaje Guerkin el comportamiento descrito en cada ejemplo. A estas tres actividades se las llama: Descubrir, formular y automatizar.
</p>
<p>
La idea es hacer cada nueva funcionalidad en partes muy pequeñas (ejemplos) e iterar rápidamente. Cada vez que se implementa un ejemplo se añade algo valioso al sistema y se está en disposición de responder a posibles cambios como resultado de la retroalimentación recogida de los expertos en el negocio. Los ejemplos documentados guían el desarrollo y permiten al equipo tener confianza y progresar en la construcción del sistema. A la documentación que se va construyendo se le llama “documentación viva” porque el código representa la documentación y la documentación refleja el conocimiento compartido del equipo sobre lo que el código hace. Cucumber es una herramienta que sirve para hacer BDD y se va a usar a continuación para mostrar un ejemplo de lo explicado hasta aquí.
</p>
<p>
El ejemplo está basado en el curso online que suministran en <a href="https://cucumber.io/school/" target="_blank">Escuela Cucumber</a> de forma gratuita, sólo hay que registrarse. El ejemplo tiene la siguiente estructura.
</p>
<p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcEmrGUIPKtut_NM9yi8iYVBJJFP8KwX5C6X9lmHCOKuoAE62gqLEkAFjmZEGZNxFbYIiHQ7AgY1-pblxu-pFC4U9VKvQzLTahFpV-XfSle8JU9647FA_VPrEOrafa30x1aogj9cf9kG8H01qAQUmvQmzAEEM2hF839zgiYRaXEwiLYEWuJxPushyt-VH1/s1288/EstructuraEjemplo.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="600" data-original-height="316" data-original-width="1288" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcEmrGUIPKtut_NM9yi8iYVBJJFP8KwX5C6X9lmHCOKuoAE62gqLEkAFjmZEGZNxFbYIiHQ7AgY1-pblxu-pFC4U9VKvQzLTahFpV-XfSle8JU9647FA_VPrEOrafa30x1aogj9cf9kG8H01qAQUmvQmzAEEM2hF839zgiYRaXEwiLYEWuJxPushyt-VH1/s600/EstructuraEjemplo.png"/></a></div>
</p>
<p>
El contenido de Belly.feature es la codificación del ejemplo en Guerkin. La idea expresada es que si comes menos de 42 galletas y pasa más de una hora vas a estar hambriento y tu estómago va a gruñir, pero si has tomado más de 42 galletas no gruñirá.
</p>
<p>
<script src="https://gist.github.com/MarisaAfuera/6442325916e5db195d76e7219a2a91f2.js"></script>
</p>
La implementación del ejemplo para que la librería de Cucumber pueda ejecutar la prueba escrita en Guerkin en Belly.feature está en StepsBelly.java.
<p>
<script src="https://gist.github.com/MarisaAfuera/6cdec97b587a72101ca1af732ed1f3ab.js"></script>
</p>
<p>
La funcionalidad del negocio está en Belly.java, esta aplicación determina si la barriga(belly) está llena o no después de haber transcurrido una hora y haber consumido una determinada cantidad de galletas.
</p>
<p>
<script src="https://gist.github.com/MarisaAfuera/a66bd3001b56ae0068275893fa2ce6b8.js"></script>
</p>
<h2>
Resumen
</h2>
<p>
Estos tres ficheros son una pequeña muestra de lo que BDD, Guerkin y Cucumber pueden hacer para mejorar el desarrollo de software.
</p>
<ul>
<li>Belly.Feature está escrito en un lenguaje entendible por el usuario y expresa lo que él espera que el sistema haga.</li>
<li>StepsBelly.java es la implementación en java de Belly.Feature, cuando se ejecuta valida lo que se espera que haga la aplicación. Hay que tener en cuenta que lo que se espera que haga la aplicación lo ha escrito el experto en el negocio.</li>
<li>Belly.java es la aplicación cuya funcionalidad se comprueba automáticamente con StepsBelly.java que se ejecuta con Cucumber.</li>
</ul>
<p>
No hay fisuras posibles entre lo que quiere el experto en el negocio y lo que codifica el desarrollador. Bueno hay que estudiar cómo usar todo esto en el mundo real, pero eso es otra historia…..
</p>Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-8850784053469356002023-06-16T11:47:00.002-07:002023-06-16T11:50:38.609-07:00JavaScript: Como asegurarse de que es una Shallow copy.<p>La forma de asegurarnos que estamos haciendo una shallow copy es: </p>
<p style="text-align:center"><code>const myShallowCopy = JSON.parse(JSON.stringify(myObj));</code></p>
<p>con <code>JSON.Stringify</code> se convierte el objeto a copiar en una cadena de caracteres y con <code>JSON.parse</code> se vuelve a convertir en objeto. De esta manera estamos creando un nuevo objeto situado en otra referencia de memoria, es decir una shallow copy.</p>
<p>¿Por qué todo este jaleo? Depende de las necesidades del algoritmo a programar, nos interesa realizar deep copy (copia profunda) o shalow copy(copia superficial). Normalmente nos interesa copia superficial, de esta manera tenemos dos objetos independientes.</p>
<h3>Diferencias entre deep y shallow copy.</h3>
<p>Shallow copy copia un objeto en otra parte de la memoria (referencia). Entonces disponemos de dos objetos iguales que son independientes.</p>
<p>Deep copy copia la referencia al objeto copiado. Realmente es como si se tienen dos nombres para un mismo objeto, si se cambia algo en uno de ellos cambia automáticamente en el otro. Los dos objetos están apuntando a la misma referencia de memoria.</p>
<h3>Ejemplo.</h3>
<p>
<code>
let obj = {a:1};<br/>
let shallowObj = {...obj};<br/>
shallowObj.a = 2;<br/>
console.log ("Shallow copy: obj "+JSON.stringify(obj)+" shallowObj "+ JSON.stringify(shallowObj));<br/>
// Shallow copy: obj {"a":1} shallowObj {"a":2}<br/>
<br/>
let deepObj = obj;<br/>
deepObj.a = 3;<br/>
console.log (" Deep copy: obj "+JSON.stringify(obj)+" deepObj "+ JSON.stringify(deepObj));<br/>// Deep copy: obj {"a":3} deepObj {"a":3}<br/>
</code>
</p>
<p><div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgnqabkGdVNb-iEsly8qAko0eiHn2Ky4NBA-xVyZEp-tIeBEj0sFV1X6-IYnj-sGQs5XpkDFb5SjxJG12ukt1Sf_FI7u9WHNphNFKNbMBcH7ojfoKbxVQUn7hMV7I6x1cXriEcGIdu88de325u7QS4ljyB-oaHT76xY5EEENQ3tc9pbRx9GdJy1TuBZg/s1650/EjemploSimple.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="600" data-original-height="936" data-original-width="1650" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgnqabkGdVNb-iEsly8qAko0eiHn2Ky4NBA-xVyZEp-tIeBEj0sFV1X6-IYnj-sGQs5XpkDFb5SjxJG12ukt1Sf_FI7u9WHNphNFKNbMBcH7ojfoKbxVQUn7hMV7I6x1cXriEcGIdu88de325u7QS4ljyB-oaHT76xY5EEENQ3tc9pbRx9GdJy1TuBZg/s600/EjemploSimple.png"/></a></div></p>
<p>La imagen muestra el comportamiento de shallow y deep copy. Cuando se modifica la shallow copy el objeto original no cambia, sin embargo sí cambia si se modifica la deep copy.</p>
<h3>Otro Ejemplo más complejo.</h3>
<p>Cuando un objeto contiene otro objeto en sus propiedades se produce una particularidad.</p>
<p>
<code>
let obj = {a:1, b: {a:1}};<br/>
let shallowObj = {...obj};<br/>
shallowObj.a = 2;<br/>
shallowObj.b.a = 2;<br/>
console.log ("Shallow copy: obj "+JSON.stringify(obj) +" shallowObj "+ JSON.stringify(shallowObj));<br/>
// Shallow copy: obj {"a":1,"b":{"a":2}} shallowObj {"a":2,"b":{"a":2}}<br/>
<br/>
obj = {a:1, b: {a:1}};<br/>
let deepObj = obj;<br/>
deepObj.a = 2;<br/>
deepObj.b.a = 2;<br/>
console.log (" Deep copy: obj "+JSON.stringify(obj)+" deepObj "+ JSON.stringify(deepObj));<br/>
// Deep copy: obj {"a":2,"b":{"a":2}} deepObj {"a":2,"b":{"a":2}}<br/>
</code>
</p>
<p>La particularidad se produce en la Shallow copy, cuando se cambia el valor de la propiedad a del objeto almacenado en la propiedad b, es decir shallowObj1.b.a. Resulta que este objeto se ha copiado por referencia, o sea es una deep copy.</p>
<p><div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsZ_vykv-yiDkMxwvHAT2C40VYHjJ9XjIw_PEnCEG0KYmlh3CCxi-rVGCKkCI9jdfgwRCZzohWDk6QgUL9ComYSfT3il6zxYz04x7HCP5sfglz6DqW_CVg7SUJMJAv1-0KfMg9xUVIvBVMlFwkLfFR14izTL_xEcURM6HnXY1ZZJC-VkiJ_gKx0lbTgg/s1650/EjemploComplejo.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="600" data-original-height="1143" data-original-width="1650" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsZ_vykv-yiDkMxwvHAT2C40VYHjJ9XjIw_PEnCEG0KYmlh3CCxi-rVGCKkCI9jdfgwRCZzohWDk6QgUL9ComYSfT3il6zxYz04x7HCP5sfglz6DqW_CVg7SUJMJAv1-0KfMg9xUVIvBVMlFwkLfFR14izTL_xEcURM6HnXY1ZZJC-VkiJ_gKx0lbTgg/s600/EjemploComplejo.png"/></a></div></p>
<p>En este caso el problema es que el objeto b que está dentro del shallowObj en vez de copiarse como un nuevo objeto se ha copiado como una referencia al objeto dentro de la propiedad b de obj. Por eso cuando se cambia <code>shallow.b.a</code> resulta que estamos cambiando también <code>obj.b.a</code>.</p>
<h3>Solución.</h3>
<p>Esto puede ser inesperado para el programador que cuando cambia el valor en la copia también está cambiando el valor en el original. Una solución a esto es utilizar la sentencia mostrada al principio del artículo. Con stringify y parse nos aseguramos de que la shallow copy es total independientemente de los objetos contenidos en propiedades y los posibles anidamientos. Al hacer el parse se crean nuevos objetos, nunca copias por referencia. Por lo tanto los objetos son independientes y se pueden manejar sin interferir los valores de uno en los valores del otro.</p>
<p>Si quieres ver un video en el que explico los ejemplos, lo puedes hacer aqui <iframe class="BLOG_video_class" allowfullscreen="" youtube-src-id="Xf02HC56SEc" width="400" height="322" src="https://www.youtube.com/embed/Xf02HC56SEc"></iframe></p>
Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-61820453557839578072023-03-17T04:05:00.005-07:002023-03-17T12:52:26.717-07:00La economía del software según J. B. Rainsberger<p>
Este artículo está basado en una conferencia de 2019 titulada “The economics of software design” de J.B. Rainsberger y que está disponible en Youtube en <a href="https://www.youtube.com/watch?v=TQ9rng6YFeY" target="_blank">ver conferencia</a> .
</p>
<p>
Lo que aquí relato es mi libre interpretación de lo que cuenta Rainsberger, lo digo porque puedo estar equivocada y tergiversar sus palabras. O sea son mis palabras, no las suyas, por si acaso. Es para que no me pase lo mismo que al tipo de la cola del cine en la película “Annie Hall” cuando habla sobre el trabajo de Marshall MacLujan <a href="https://www.youtube.com/watch?v=OUKMdGi9oLo">ver escena</a>.
</p>
<p>
El objetivo de la conferencia es explicar porque son necesarias prácticas ágiles a la hora de desarrollar software. Rainsberger con mucho talento sigue un hilo sólido que explica a desarrolladores y no desarrolladores porqué usar practicas ágiles va a mejorar los sistemas de información.
</p>
<p>
Rainsberger dice que hay tres asuntos importantes en los que hay que centrar la atención cuando se desarrolla software:
<ul>
<li>Las funcionalidades desarrolladas (Features)</li>
<li>El diseño del software (Design)</li>
<li>La retroalimentación (Feedback)</li>
</ul>
</p>
<h3>Funcionalidades desarrolladas</h3>
<p>
La refactorización es la piedra angular del desarrollo de código. Esta refactorización facilita mejorar el coste marginal. El coste marginal es un término financiero que se puede definir como el incremento de coste al producir N+1 unidades de determinado producto, respecto al coste de producción de N unidades. Llevando esto al mundo software, se puede traducir en el coste de añadir una nueva funcionalidad o cambiar una funcionalidad ya existente. Es menor de añadir o modificar funcionalidades si el sistema está bien diseñada, es decir no es un galimatías. Los patrocinadores del software (financiero de la empresa u organismo) entienden de costes marginales, los desarrolladores de diseño del software. Entonces, si para tener un mejor coste marginal es necesario refactorizar los promotores entienden que refactorizar es necesario, los desarrolladores ya lo saben. La forma de refactorizar constantemente es utilizar TDD (Test Driven Development).
</p>
<h3>Diseño del software</h3>
<p>
Para su exposición Rainsberger utiliza el siguiente gráfico.
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlEAk-4NgPfqoVzUVsHjab-LdBMJOJsWRk5tntExrW--xRDDMr3b483qXPQILY_I3f_o_C0-9I4eYHoZZ0MM2dQKe-mKwuNpGa7poTivztlrgIS43CZO8o9vJJVxFUOcy-Hqyz6pxFeSnbYAx1x7-WOAA4PvfBv7s1WqeCyWaFNw5GE1AtI0_3R2tZXg/s2744/Gr%C3%A1ficoRainsburger.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" height="320" data-original-height="2744" data-original-width="2448" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlEAk-4NgPfqoVzUVsHjab-LdBMJOJsWRk5tntExrW--xRDDMr3b483qXPQILY_I3f_o_C0-9I4eYHoZZ0MM2dQKe-mKwuNpGa7poTivztlrgIS43CZO8o9vJJVxFUOcy-Hqyz6pxFeSnbYAx1x7-WOAA4PvfBv7s1WqeCyWaFNw5GE1AtI0_3R2tZXg/s320/Gr%C3%A1ficoRainsburger.jpg"/></a></div>
</p>
<p>
Aquí la curva representada por g representa el aumento del coste de seguir modificando un sistema que no se desarrolla con “Diseño Evolutivo”. Inicialmente desarrollar el sistema es menos costoso, pero con el tiempo el coste de mantenerlo se eleva exponencialmente, según Rainsberger siguiendo el comportamiento del interés compuesto según Bernoulli, de hay la formula (1+1/n)ⁿ -> e. Sin embargo la curva representada por f corresponde a los sistemas que se desarrollan con “Diseño Evolutivo” (básicamente empleando TDD), en estos el diseño está mejorando constantemente y eso contribuye a que aunque cada vez el sistema sea más complejo el crecimiento de costes sea mucho más moderado. En términos más vulgares que el galimatías sea menor, aunque la complejidad sea mayor.
</p>
<p>
También dice Rainsberger que el punto t₀ en el caso de los sistemas que no se desarrollan con "Diseño Evolutivo" es el momento en que económicamente es más rentable tirar el sistema y hacerlo de nuevo. Cómo según él nadie sabe calcular cuando llega ese momento, es mejor trabajar con “diseño evolutivo” para evitar el desastre.
</p>
<h3>Retroalimentación</h3>
<p>En cuanto a la producción del software existe un modelo clásico llamado “En cascada” que implica las fases:</p>
<p align='center'>Requisitos -> Análisis-> Diseño-> Codificación -> Pruebas -> Puesta en marcha</p>
<p>En este modelo la retroalimentación se ejecuta demasiado tarde. Esto provoca que la cantidad de re-trabajo suela ser ingente porque cuando algo no se ajusta a lo esperado ya hay mucho que cambiar.</p>
<p>En “XP (eXtreme Programming de 1999)” se expuso que era mejor realizar un ciclo de desarrollo y pruebas constante que pusiera en evidencia si lo que se estaba desarrollando era lo que se necesitaba. XP y a continuación Agile aconsejan prácticas que mejoran la retroalimentación: pequeños ciclos de desarrollo, pruebas unitarias para conocer el estado interno del sistema y pruebas de aceptación para saber si el sistema está de acuerdo con las necesidades del usuario.</p>
<p>Rainsberger expone que las técnicas para llevar esto a cabo son TDD y BDD. También las prácticas de DevOps ayudan a la retroalimentación y facilitan la labor coordinada de los equipos de desarrollo y operaciones.</p>
<h3>Conclusiones</h3>
<p>Esta conferencia apoya de forma empírica y heurística el desarrollo basado en técnicas ágiles. </p>
<p>No hay fórmulas mágicas, pero desarrollar software no es fácil y yo también estoy convencida de que todas las prácticas ágiles contribuyen a que el mundo del desarrollo de software mejore.</p>
<p>Buenas noticias, eso nos beneficia a todos a los informáticos y a los no informáticos.</p>Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-15671834532231261552023-02-20T09:28:00.003-08:002023-06-19T02:45:51.887-07:00Expresiones regulares en JavaScript<h3 id="sigil_toc_id_1">Qué es una expresión regular y como se crea en JavaScript.</h3>
<p>Una expresión regular es una secuencia de caracteres que conforma un patrón de búsqueda. Este patrón se utiliza para buscar dentro conjuntos de caracteres contenidos en: literales, variables, ficheros, etc. y comprobar si hay coincidencia o no en la búsqueda.</p>
<p>Las búsquedas con patrones tienen muchas utilidades. Por ejemplo:
</p>
<ul>
<li>Buscar una subcadena dentro de una cadena de caracteres.</li>
<li>Reemplazar partes de una cadena por otras subcadenas.</li>
<li>Validar el formato de un dato.</li>
<li>Formatear datos.</li>
<li>Filtrar información y extraer datos que cumplan ciertas condiciones.</li>
</ul>
Las expresiones regulares no son complicadas, pero en una primera aproximación pueden intimidar. Cuando se comprenden y se saben manejar la perspectiva cambia y se convierten en grandes aliados de los programadores.
<p></p>
<p>Un patrón es un objeto RegExp de JavaScript que se crea escribiendo caracteres entre dos barras oblicuas. Luego se puede utilizar de distintas formas, por ejemplo con el método <code>test()</code> que es uno de los métodos del objeto patrón. Un ejemplo:</p>
<div class="divCode"><pre><code>
let patron = /verde/;
console.log (patron.test("¡Qué verde era mi valle!")); // true
</code></pre>
</div>
<p>Este patrón <code>/verde/</code> busca el conjunto de caracteres verde en la cadena <code>"¡Qué verde era mi valle!"</code> y como hay coincidencia devuelve <code>true</code>.</p>
<p>Hay más métodos de los objetos JavaScript que manejan los patrones. Por ejemplo el método <code>search()</code> del objeto String. Este método devuelve -1 si no encuentra coincidencia y un número positivo que indica la posición donde encuentra el patrón. Por ejemplo:
</p>
<div class="divCode"><pre><code>
"!Qué verde era mi valle¡".search(patr);
</code></pre>
</div>
<p>
devuelve un 5 que es la posición de la cadena donde empieza la palabra verde si se cuenta de izquierda a derecha en la cadena empezando por 0.
</p>
<h3 id="sigil_toc_id_2">Metacaracteres en las expresiones regulares.</h3>
<p>En los patrones se usan caracteres que tienen significados especiales y es lo que se llama metacaracteres. Por ejemplo el caracter <code>.</code> en un patrón significa coincidencia con cualquier caracter. Un ejemplo:
</p>
<div class="divCode"><pre><code>
let patr = /r..a/; // Busca una r, 2 caracteres cualesquiera y una a.
let cadena = "La casa roja";
console.log (patr.test(cadena)); // true
cadena = "La casa rosa";
console.log (patr.test(cadena)); // true
cadena = "El ron era bueno";
console.log (patr.test(cadena)); // false
cadena = "El remo se rompió";
console.log (patr.test(cadena)); // false
</code></pre>
</div>
<p>
Hay muchos metacaracteres para crear expresiones regulares y conseguir con los patrones realizar busquedas complejas. Estos patrones evitan muchas veces tener que crear largos algoritmos de programación. Por ejemplo:
</p>
<div class="divCode"><pre><code>
/[a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)*@[a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)*[.][a-zA-Z]{2,5}/
</code></pre>
</div>
<p>
este patrón sirve para comprobar si una dirección de correo electrónico tiene un formato correcto. De esta forma con esta sola línea se consigue evitar tener que idear y codificar un algoritmo que lo compruebe y cuantas menos líneas de código escritas, menos líneas de código a mantener.
</p>
<h3 id="sigil_toc_id_3">Ejemplo de dos metacaracteres usados normalmente.</h3>
<!-- . -->
<p><i>Metacaracter</i> ➝ <code><b>.</b></code></p>
<p><i>Significado</i> ➝ Cualquier caracter.</p>
<p><i>Ejemplo:</i>
</p>
<div class="divCode"><pre><code>
let patr = /a..a./;
let cadena = "ambar";
console.log (patr.test(cadena)); // true
cadena = "amigo";
console.log (patr.test(cadena)); // false
</code></pre>
</div>
<p></p>
<!-- \d -->
<p><i>Metacaracter</i> ➝ <code><b>\d</b></code></p>
<p><i>Significado</i> ➝ Cualquier caracter que sea un número arábigo, es decir 0, 1 ,2 ,3 ,4 ,5 ,6 , 7 ,8 o 9</p>
<p><i>Ejemplo:</i>
</p>
<div class="divCode"><pre><code>
let patr = /\d/;
let cadena = "Juan tiene 18 años";
console.log (patr.test(cadena)); // true
cadena = "Juan tiene dieciocho años";
console.log (patr.test(cadena)); // false
</code></pre>
</div>
<p></p>
<p>
Si necesitas más información sobre expresiones regulares y más ejemplos puedes consultar el libro
<a href="http://www.amazon.es/dp/B0BRX1YKN1" target="_blank">Uso de expresiones regulares en JavaScript</a>
</p>
<p>
O si lo prefieres puedes inscribirte en este curso
<a href="https://www.udemy.com/course/expresiones-regulares-en-javascript/?referralCode=BADF831436191A0B033F" target="_blank">Expresiones regulares en JavaScript</a>
</p>Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-66634261470184720182023-01-10T09:04:00.004-08:002023-01-10T10:58:58.878-08:00JavaScript: Guia rápida de expresiones regulares <style>
.grande {font-size: 18px;
}
</style>
<p>
Aquí hay un resumen de los meta-caracteres y otras estructuras más empleados en las expresiones regulares. Si necesitas una explicación mas detallada y ver algunos ejemplos puedes consultar el libro
<a href="http://www.amazon.es/dp/B0BRX1YKN1" target="_blank">Uso de expresiones regulares en JavaScript</a>
</p>
<br/>
<h2 id="sigil_toc_id_21">Metacaracteres generales</h2>
<br/>
<table cellspacing="0" cellpadding="0" border="1" align="center">
<tbody>
<tr>
<th>Metacaracter</th>
<th>Significado</th>
</tr>
<tr>
<td align="center" width="30%">
<code class="grande">\d</code>
</td>
<td>
Cualquier caracter que sea un número arábigo, es decir 0, 1 ,2 ,3 ,4 ,5 ,6 , 7 ,8 o 9
</td>
</tr>
<tr>
<td align="center">
<code class="grande">\D</code>
</td>
<td>
Cualquier que no sea un número arábigo, es decir 0, 1, 2, 3, 4, 5, 6, 7, 8 o 9
</td>
</tr>
<tr>
<td align="center">
<code class="grande">\w</code>
</td>
<td>
Cualquier caracter del alfabeto latino básico es decir letras minúsculas, letras mayúsculas y guión de subrayado
</td>
</tr>
<tr>
<td align="center">
<code class="grande">\W</code>
</td>
<td>
Cualquier caracter que no sea del alfabeto latino básico es decir letras minúsculas, letras mayúsculas, números arábigos y guión de subrayado
</td>
</tr>
<tr>
<td align="center">
<code class="grande">\s</code>
</td>
<td>
Encuentra coincidencia cuando hay un espacio u otros caracteres no imprimibles
</td>
</tr>
<tr>
<td align="center">
<code class="grande">\^</code>
</td>
<td>
Comprueba el principio de la cadena
</td>
</tr>
<tr>
<td align="center">
<code class="grande">\$</code>
</td>
<td>
Comprueba el final de la cadena
</td>
</tr>
<tr>
<td align="center">
<code class="grande">\</code>
</td>
<td>
Indica que el siguiente caracter, tiene que ser tratado de forma especial. Es útil para tratar meta-caracteres como caracteres especiales y para tratar caracteres normales como meta-caracteres
</td>
</tr>
<tr>
<td align="center">
<code class="grande">\b</code>
</td>
<td>
Comprueba límites de palabra. Un límite de palabra es la posición donde un caracter de palabra no es seguido o precedido por otro caracter de palabra. Los caracteres de palabra son: letras del alfabeto latino en mayúsculas o minúsculas, números arábigos o sea los caracteres del 0 al 9 y el caracter de subrayado
</td>
</tr>
<tr>
<td align="center">
<code class="grande">\B</code>
</td>
<td>
Comprueba límites de no palabra. Un límite de no palabra es la posición donde un caracter de palabra es seguido o precedido por otro caracter de palabra. Los caracteres de palabra son: letras del alfabeto latino en mayúsculas o minúsculas, números arábigos o sea los caracteres del 0 al 9 y el caracter de subrayado. Es decir busca que un caracter esté seguido o precedido por otro del mismo tipo, de palabra o de no palabra
</td>
</tr>
<tr>
<td align="center">
<code class="grande">[abc] o [a-c]</code>
</td>
<td>
Encuentra coincidencia si hay alguno de los caracteres que aparecen entre corchetes en la cadena. También se pueden especificar rangos de caracteres mediante un guión, así [abc] es lo mismo que [a-c]
</td>
</tr>
<tr>
<td align="center">
<code class="grande">[^abc] o [^a-c]</code>
</td>
<td>
Encuentra coincidencia si encuentra algún caracter distinto de los que aparecen entre corchetes en la cadena. También se pueden especificar rangos de caracteres mediante un guión, así [^abc] es lo mismo que [^a-c]
</td>
</tr>
<tr>
<td align="center">
<code class="grande">\t</code>
</td>
<td>
Hay coincidencia si encuentra un tabulador horizontal en la cadena. Hay que tener en cuenta que este caracter es un Non Printable Character y los editores normalmente no lo muestran como tal sino que lo interpretan como una orden, en este caso que el caracter siguiente se muestre más a la derecha
</td>
</tr>
<tr>
<td align="center">
<code class="grande">\r \n \v \f</code>
</td>
<td>
Estos al igual que el anterior son Non Printable Characteres y los editores normalmente no lo muestran como tal sino que lo interpretan como una orden. Cada uno tiene un significado distinto: \r carriage return (junto a \n salto de línea), \n linefeed (salto de línea), \v vertical tab y \f form-feed (salto de página)
</td>
</tr>
<tr>
<td align="center">
<code class="grande">x|y</code>
</td>
<td>
Disyunción: coincide si hay x o y. Cada componente separado por | se llama alternativa
</td>
</tr>
</tbody>
</table>
<br/>
<h2 id="sigil_toc_id_22">Metacaracteres cuantificadores</h2>
<br/>
<table cellspacing="0" cellpadding="0" border="1" align="center">
<tbody>
<tr><th>Metacaracter</th>
<th>Significado</th>
</tr>
<tr>
<td align="center" width="30%">
<code class="grande">x*</code>
</td>
<td>
El item precedente 'x' se repite 0 o más veces
</td>
</tr>
<tr>
<td align="center">
<code class="grande">x+</code>
</td>
<td>
El item precedente 'x' se repite 1 o más veces
</td>
</tr>
<tr>
<td align="center">
<code class="grande">x?</code>
</td>
<td>
El item precedente 'x' se repite 0 o 1 vez
</td>
</tr>
<tr>
<td align="center">
<code class="grande">x{n}</code>
</td>
<td>
El item precedente 'x' se repite exactamente n veces
</td>
</tr>
</tbody>
</table>
<br/>
<h2 id="sigil_toc_id_23">Grupos</h2>
<br/>
<table cellspacing="0" cellpadding="0" border="1" align="center">
<tbody>
<tr><th>Grupo</th>
<th>Significado</th>
</tr>
<tr>
<td align="center" width="30%">
<code class="grande">(abc)</code>
</td>
<td>
Busca la cadena abc
</td>
</tr>
<tr>
<td align="center">
<code class="grande">(/w/w)</code>
</td>
<td>
Busca 2 caracteres del alfabeto latino seguidos
</td>
</tr>
<tr>
<td align="center">
<code class="grande">(?<g>abc)</code>
</td>
<td>
El grupo se llama g. Luego se puede usar con \k<g>
</td>
</tr>
<tr>
<td align="center">
<code class="grande">(([0-9]){2}-){3}</code>
</td>
<td>
Los grupos se pueden anidar. En este caso el primer grupo es un numero que se tiene que repetir 2 veces seguido de un guión es el segundo grupo que anida al primero. Luego todo eso se repite 3 veces
</td>
</tr>
</tbody>
</table>
<br/>
<h2 id="sigil_toc_id_24">Flags</h2>
<br/>
<table cellspacing="0" cellpadding="0" border="1" align="center">
<tbody>
<tr><th>Flag</th>
<th>Significado</th>
</tr>
<tr>
<td align="center" width="10%">
<code class="grande">i</code>
</td>
<td>
Encuentra coincidencia sin distinguir mayúsculas de minúsculas
</td>
</tr>
<tr>
<td align="center">
<code class="grande">g</code>
</td>
<td>
Encuentra todas las coincidencias del patrón en la cadena
</td>
</tr>
<tr>
<td align="center">
<code class="grande">m</code>
</td>
<td>
Significa busqueda multilínea. Solo es aplicable a los metacarateres ^ y $ de principio y final de línea
</td>
</tr>
<tr>
<td align="center">
<code class="grande">s</code>
</td>
<td>
Es aplicable al metacaracter .. Cuando se usa el flag s el . encuentra coincidencia con salto de línea \n
</td>
</tr>
<tr>
<td align="center">
<code class="grande">u</code>
</td>
<td>
JavaScript utiliza la codificación Unicode, esto determina como se almacenan internamente los caracteres en memoria. Existen caracteres que se guardan de 2 bytes (16 bits de 0s y 1s) y otros que se guardan en 4 bytes. Hay que tener en cuenta que Unicode tiene combinaciones de 0s y 1s para representar los caracteres de cualquier idioma, una a sería 01000001 en binario o 41 en hexadecimal.<br/> Para construir patrones para Unicode se usa el metacaracter \p junto con otros caracteres que se ponen entre {}, por ejemplo {Sc} significa symbol y currency (símbolo y moneda)
</td>
</tr>
<tr>
<td align="center">
<code class="grande">y</code>
</td>
<td>
Busca el patrón en una posición determinada dentro de la cadena. Para establecer la posición en la que buscar se usar la propiedad lastIndex de RegExp
</td>
</tr>
</tbody>
</table>
<br/>
<h2 id="sigil_toc_id_25">Objetos para manejar patrones</h2>
<br/>
<table cellspacing="0" cellpadding="0" border="1" align="center">
<tbody>
<tr><th>Objeto.Método</th>
<th>Uso</th>
</tr>
<tr>
<td align="center" width="30%">
<code class="grande">RegExp.text()</code>
</td>
<td>
El método <code>test()</code> ejecuta una busqueda del patrón dentro de una cadena de caracteres (string), devolviendo <code>true</code> si lo encuentra o <code>false</code> sino lo encuentra
</td>
</tr>
<tr>
<td align="center">
<code class="grande">RegExp.exec()</code>
</td>
<td>
El método <code>exec()</code> realiza una búsqueda para encontrar el patrón dentro de una cadena de caracteres (string) y devuelve un array con los resultados. Sino hay coincidencias devuelve <code>null</code>
</td>
</tr>
<tr>
<td align="center">
<code class="grande">String.match()</code>
</td>
<td>
Con la bandera g de global, este método devuelve un array con las coincidencias encontradas
</td>
</tr>
<tr>
<td align="center">
<code class="grande">String.matchAll()</code>
</td>
<td>
Debe llevar la bandera g y devuelve un iterador que contiene las coincidencias del patrón encontradas en la cadena
</td>
</tr>
<tr>
<td align="center">
<code class="grande">String.split()</code>
</td>
<td>
Separa la cadena por el patrón especificado y crea un array con las subcadenas obtenidas
</td>
</tr>
<tr>
<td align="center">
<code class="grande">String.search()</code>
</td>
<td>
Busca la primera coincidencia del patrón y devuelve la posición dentro de la cadena en la que lo encuentra
</td>
</tr>
<tr>
<td align="center">
<code class="grande">String.replace()</code>
</td>
<td>
Reemplaza una cadena o las coincidencias del patrón con la cadena especificada. El método replace tiene dos argumentos, uno para especificar la cadena o patrón a reemplazar y el segundo para especificar conqué hay que reemplazarlo
</td>
</tr>
</tbody>
</table>Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-39234929401697993102022-08-16T12:17:00.002-07:002022-08-16T12:18:42.735-07:00Qué es Cloud Computing<p>Estoy asistiendo a un curso online en <a href="" target="_blank">https://www.edx.org/es</a> y la definición e introducción que hacen para explicar "La Nube" me ha parecido muy interesante y quiero compartirla con vosotros.</p>
<p>Cloud es la entrega de recursos para computación a demanda. En lugar de depender de un servicio físico instalado, se tiene acceso a una estructura donde el software y/o el hardware están virtualmente integrados.</p>
<p>NIST(National Institute of Standards and Technology) define Cloud como: Un modelo para proporcionar recursos compartidos que son fácilmente aprovisionados, configurados y entregados por parte de el proveedor del servicio.</p>
<h3>Características esenciales de Cloud</h3>
<ol>
<li>
Autoservicio a demanda.- los recursos de Cloud se obtienen sin necesidad de intervención humana. Estos servicios pueden ser: potencia de procesamiento, capacidad de almacenamiento y capacidad de red.
</li>
<li>
Acceso a la red.- A los recursos de Cloud se puede acceder vía red desde mecanismos y plataformas estándar cómo móviles, tabletas, portátiles o estaciones de trabajo.
</li>
<li>
Zona común de recursos.- Esto permite a los proveedores de servicios Cloud optimizar el uso de dichos recursos, permitiendo ofrecer a sus clientes servicios a precios mejores que los que conseguirían si los recursos los adquirieran de forma privada.
</li>
<li>
Elasticidad.- Se obtienen más recursos cuando se necesitan y se devuelven cuando no se usan.
</li>
<li>
Servicios a medida.- Solo se paga por lo que se usa. El uso de recursos se monitoriza, se mide y se informa de forma trasparente sobre su utilización.
</li>
</ol>
<h3>Modelos de despliegue de Cloud</h3>
<ul>
<li>
Público.- Los servicios se suministran desde infraestructuras (hardware y software) propiedad del proveedor a las que se accede desde internet y estas infraestructuras se comparten entre varias compañías.
</li>
<li>
Privado.- Los servicios se suministran desde infraestructuras (hardware y software) propiedad del proveedor a las que se accede desde internet y estas infraestructuras son de uso privado de una compañía.
</li>
<li>
Híbrido.- Una mezcla de público y privado
</li>
</ul>
<h3>Modelos de servicio de Cloud</h3>
<ul>
<li>
Infraestructura como servicio.- Proporciona recursos físicos como servidores, redes, almacenamiento de datos sin necesidad de instalarlos ni mantenerlos. Esto se ve a menudo como IaaS por sus siglas en inglés Infraestructure as a service. Un ejemplo, es cuando se aloja una web en un servidor que se contrata de forma remota. El servidor podemos decir que es virtual puesto que no tenemos ninguna máquina real.
</li>
<li>
Plataforma como servicio.- Proporciona acceso a una plataforma que normalmente tiene hardware y software, generalmente lo que se necesita para desarrollar y desplegar aplicaciones a usuarios en internet. Esto se conoce a menudo como PaaS por sus siglas en inglés Platform as a Service. Un ejemplo de esto es si contratamos un servidor(hardware) con un servidor de aplicaciones(software) ya instalado en el que vamos a desplegar nuestra web.
</li>
<li>
Software como servicio.- Es un modelo de licenciado y entrega en el cual las aplicaciones están alojadas y licenciadas en forma de subscripción, algunas veces se conoce este modelo como “software a demanda”. Este modelo se conoce como SaaS por sus siglas en inglés Software as a Service. Un ejemplo es cuando contratamos una aplicación de cualquier tipo de la que vamos a hacer uso en remoto, normalmente se paga por usuario.
</li>
</ul>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9YNnHBWM44VbO34Z4aUyxU36k814KxrUmhD2plA1jBzARt-Z9LB4cnChJyolzd6UwV3nuJdz20J99ZE57B8tRFTcIAggKAEdWnPF_yeZq2BG8TDgolxb--T3e76_E8N0TeMyWUx5cRkgeaodS5utIRBkqXFS03jNewjMZtlgiLmMxDFsMm6jBo9iB9A/s574/ModelosCloud.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="271" data-original-width="574" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9YNnHBWM44VbO34Z4aUyxU36k814KxrUmhD2plA1jBzARt-Z9LB4cnChJyolzd6UwV3nuJdz20J99ZE57B8tRFTcIAggKAEdWnPF_yeZq2BG8TDgolxb--T3e76_E8N0TeMyWUx5cRkgeaodS5utIRBkqXFS03jNewjMZtlgiLmMxDFsMm6jBo9iB9A/s400/ModelosCloud.png"/></a></div>Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-85151702959693580122022-07-29T11:30:00.001-07:002022-07-29T11:33:26.408-07:00JavaScript: Que es Node con un ejemplo.<p>JavaScript es un lenguaje de programación que inicialmente se diseñó para ser ejecutado en el buscador. Es decir, se construían páginas html que para poder contener código ejecutable se cargaban con scripts que no eran otra cosa que módulos con sentencias JavaScript que dotaban y dotan a las páginas html de interactividad con el usuario. Por ejemplo, si se clica un botón se abre una nueva ventana.</p>
<p>JavaScript es un lenguaje de programación que inicialmente se diseñó para ser ejecutado en el buscador. Es decir, se construían páginas html que para poder contener código ejecutable se cargaban con scripts que no eran otra cosa que módulos con sentencias JavaScript que dotaban y dotan a las páginas html de interactividad con el usuario. Por ejemplo, si se clica un botón se abre una nueva ventana.</p>
<p>Para ello lo primero es instalar Node que se puede hacer desde <a href="https://nodejs.org/en/download/">https://nodejs.org/en/download/</a></p>
<p>Después de la instalación podemos escribir en la consola del sistema el comando node y se recibe información de la versión que se ha instalado:</p>
<p><center><font face=”Courier New” size="4pt"><b>Welcome to Node.js v14.16.0.</b></font></center></p>
<p>Un ejemplo de uso de Node es el siguiente. Escribimos un módulo en lenguaje JavaScript con el siguiente contenido:</p>
<p><script src="https://gist.github.com/MarisaAfuera/78de81d3d2faabdaefae10e30edeba52.js"></script></p>
<p>Se guarda este módulo con el nombre holamundo.js. Si se ejecuta en la consola del sistema el comando node holamundo, se arranca un servicio en 127.0.0.1:1234 y por ello en la consola del sistema se verá:</p>
<p><center><font face=”Courier New” size="4pt"><b>Servidor corriendo en http://127.0.0.1:1234</b></font></center></p>
<p>A continuación abriendo un buscador y escribiendo http://127.0.0.1:1234 veremos</p>
<p><div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaLWpXTImbIYcoRKslXadZx85TtOhp5RRD1bu5gGZI-NPBNnMyMfeC31c6Dvvi4SgUwrDG5-kKJj9kojxp1ig9f8j27iXkL128MHb65SUbNkxhglNixXDWK7kmImMRMZWfCSAEHBu_LLX7UWIKfcBOldu0uOoNoRSbzYjJIMNCRd6h761YsVMhMqoQRg/s481/Resp.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="216" data-original-width="481" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaLWpXTImbIYcoRKslXadZx85TtOhp5RRD1bu5gGZI-NPBNnMyMfeC31c6Dvvi4SgUwrDG5-kKJj9kojxp1ig9f8j27iXkL128MHb65SUbNkxhglNixXDWK7kmImMRMZWfCSAEHBu_LLX7UWIKfcBOldu0uOoNoRSbzYjJIMNCRd6h761YsVMhMqoQRg/s400/Resp.png"/></a></div></p>
<h3>Para terminar</h3>
<p>Node permite que la programación de servidor se escriba en javascript al igual que la del cliente. Node ha tenido bastante éxito y actualmente muchos sistemas tiene su frontend e incluso su backend escritos con JavaScript haciendo uso de este software.
Node permite escribir código asíncrono para mejorar la interacción con el usuario y no hacerle esperar cuando no es necesario, además esta orientado a eventos y basado en el motor V8 de Google. Pero eso es otra historia…</p>Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-31644322598692921412022-07-15T08:33:00.004-07:002022-07-18T02:25:54.937-07:00Javascript: Ejemplo de CRUD con MariaDB y Node Express<p>Con carácter general para establecer la conexión</p><br/>
<script src="https://gist.github.com/MarisaAfuera/a56bd05a4104e187e015870d255c01f8.js"></script>
<p>Leer todas las filas</p><br/>
<script src="https://gist.github.com/MarisaAfuera/4bd7e71489cf034f9a7ab572955cc899.js"></script>
<p>Leer una fila por identificador</p><br/>
<script src="https://gist.github.com/MarisaAfuera/36bce5d84a0b392b8aac70d1799fc413.js"></script>
<p>Crear una fila</p><br/>
<script src="https://gist.github.com/MarisaAfuera/49afd97004467b801abfd88016c99c99.js"></script>
<p>Modificar una fila</p><br/>
<script src="https://gist.github.com/MarisaAfuera/2b658aa92f96ef32531bd4083c0e9134.js"></script>
<p>Borrar una fila</p><br/>
<script src="https://gist.github.com/MarisaAfuera/11d0eea849d134ad5f44ba7b11b19e02.js"></script><br/>
<p> Espero que sea de ayuda para algun abnegado programador </p
Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-38719496171210038192022-03-22T10:16:00.003-07:002022-03-28T10:48:57.835-07:00Para qué sirve Kubernetes: un ejemplo<head>
<style type="text/css">
.codigo {
font-family: Courier New;
font-size: 12px;
}
</style>
</head>
<h3>Para qué sirve Kubernetes.</h3>
<p>El despliegue de aplicaciones está evolucionando para facilitar a los ingenieros del software la tarea. Parece una contradicción que los ingenieros no dispongan de los mejores productos software para suministrarles ayuda en su trabajo, pero haciendo honor al dicho “en casa de herrero, cuchillo de palo”.</p>
<p>En los orígenes, no hace demasiado tiempo, las aplicaciones eran monolíticas e incluían grandes áreas de funcionalidad. En estos momentos el despliegue era algo manual que no comportaba la misma problemática que actualmente, puesto que el despliegue de un sistema no interfería con otros. Cada sistema era estanco y auto-contenido y las dependencias entre sistemas eran mínimas.</p>
<p>Con el advenimiento del micro-servicio las cosas han cambiado. Ahora los sistemas no son obligatoriamente monolíticos, hay otras opciones. Un sistema se puede construir en numerosas pequeñas partes que tienen que colaborar para suministrar la funcionalidad completa. Esta forma de desarrollar sistemas contribuye a que los desarrolladores puedan ser más efectivos a la hora de incorporar nuevas funcionalidades a los programas y también para llevar a cabo su mantenimiento tanto de eliminación de errores como de incorporación de mejoras. No es aceptable hoy en día que un cambio en una aplicación sea largo y tedioso, las organizaciones necesitan que sus sistemas evolucionen al mismo ritmo que suceden los acontecimientos.</p>
<p>En este escenario, el despliegue de sistemas es el despliegue de sus pequeñas partes. Esas partes tienen que trabajar de forma orquestada como un equipo en el que cada parte hace lo que se espera de ella y de forma coordinada con el resto de las partes.</p>
<p>Entonces surge un problema que antes no existía, orquestar adecuadamente todas las partes o micro-servicios. Los micro-servicios tienen dependencias, en el mundo del desarrollo actual los programadores hacen uso de librerías para llevar a cabo funcionalidades ya resueltas y que han sido programadas por otros. Esto hace que normalmente un desarrollo dependa de las librerías en las cuales se apoya. Esto produce muchos quebraderos de cabeza a los ingenieros que tienen que desplegar software, porque si se despliegan dos sistemas que dependen de una misma librería esta librería tiene ser utilizada exactamente en la misma versión. En caso contrario surgen los problemas de incompatibilidades.</p>
<p>Para esto se ideó la tecnología de contenedores. En esta tecnología cada micro-servicio se empaqueta con sus librerías y hay automatismos (capas) que se encargan de controlar las versiones de las librerías comunes y otros elementos. En este ejemplo se va a utilizar Docker como tecnología de contenedores.</p>
<p>Con Docker no tenemos problemas dependencias, pero surgen problemas de gestión de los numerosos contenedores que tiene que manejar el equipo de operaciones. Cuantos contenedores están activos, que recursos consume cada uno, es necesario replicar alguno de ellos para que no se produzcan cuellos de botella, se ha caído alguno, están en la versión adecuada, es necesario dar marcha atrás en un despliegue, etc.</p>
<p>Para esta gestión viene al rescate Kubernetes.</p>
<h3>Qué es Kubernetes.</h3>
<p>Kubernetes también conocido como K8s es un sistema open-source para la automatización del despliegue, escalado y gestión de aplicaciones contenorizadas.</p>
<p>Un cluster Kubernetes está formado por componentes que sirven para gestionar un conjunto de máquinas llamadas nodos.</p>
<p>No se van a describir aquí todos los tipos de componentes que existen en Kubernetes. Solo se van a exponer aquellos componentes de los que hace uso el ejemplo que aquí se explica.</p>
<p>El componente de orden superior que se utiliza es el Deployment que representa un despliegue. En el ejemplo el Deployment tiene un Pod, un Service y varios ReplicaSet. Los Pod albergan contenedores, los ReplicaSet se encargan de mantener activas tantas copias de un pod como se hayan establecido. Los servicios exponen los pods, es decir los contenedores que incluyen como un servicio de red.</p>
<p>Para ilustrar los componentes que utiliza el ejemplo, se utiliza la siguiente figura:</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiX7Utw5uhF2COWTo-rWaWa1youH8LCDkwqUewuw60kKWnMAZYhy1a7R1fHKB6nn_hfPOjmNIAshQGjNwgVJegfT6d4s3VyAHsNAFizcyuozgHZX2UFiyali-KmYlfCiPaCG2BcTYw64u_2TXxxGf3iR1xDfM9JJapVr3174GfYyAXOwGdSIUeLcGujwA/s559/ComponentesKubernetes.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="495" data-original-width="559" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiX7Utw5uhF2COWTo-rWaWa1youH8LCDkwqUewuw60kKWnMAZYhy1a7R1fHKB6nn_hfPOjmNIAshQGjNwgVJegfT6d4s3VyAHsNAFizcyuozgHZX2UFiyali-KmYlfCiPaCG2BcTYw64u_2TXxxGf3iR1xDfM9JJapVr3174GfYyAXOwGdSIUeLcGujwA/s400/ComponentesKubernetes.png"/></a></div>
<h3>Ejemplo de Uso de Kubernetes</h3>
<p>Se crea un contenedor que incluye un servidor web nginx que muestra una página html. Para ello se realizan las siguientes acciones:</p>
<ol>
<li>Instalar Docker <a href="https://docs.docker.com/get-docker/">https://docs.docker.com/get-docker/</a></li>
<li>Crear un contenedor Docker</li>
<ul>
<li>
Crear un contenedor Docker que incluye: un servidor web nginx, una página html, una hoja de estilos y dos imágenes. Para construir un contenedor hay que crear un fichero con nombre dockerfile que describe su contenido. En el caso del ejemplo:
<div class="codigo">
FROM nginx<br>
COPY pagina.html /usr/share/nginx/html<br>
COPY pagina.css /usr/share/nginx/html<br>
COPY LogoDocker.png /usr/share/nginx/html<br>
COPY LogoKubernetes.png /usr/share/nginx/html<br>
</div>
</li>
<li>
En el directorio donde está el dockerfile se ejecuta el comando para crear el contenedorcon el comando:
<div class="codigo">docker build -t containerprueba .</div>
</li>
</ul>
<li>Se publica en un registro de contenedores, para luego usarlo desde kubernetes. En este caso en: <a href="http://hub.docker.com">http://hub.docker.com</a>
con el nombre <div class="codigo">marisaafuera/containerprueba</div>
</li>
<li>Instalar Minikube <a href="https://minikube.sigs.k8s.io/docs/start/">https://minikube.sigs.k8s.io/docs/start/</a>
y arrancarlo. Minikube es una herramienta que administra maquinas virtuales en donde corre una instancia de Kubernetes en un solo nodo y es útil a efectos de aprendizaje y pruebas.
</li>
<li>Crear un deployment en kubernetes (se crean automáticamente el pod y el servicio) con el comando:
<div class="codigo">kubectl create deployment containerprueba --image=marisaafuera/containerprueba</div>
</li>
<li>Exponerlo en Kubernetes para que sea accesible con:
<div class="codigo">kubectl expose deployment containerprueba --type=LoadBalancer --port=8090 </div>
</li>
<li>
Ahora debería de funcionar <a href="http://localhost:8090/pagina.html">http://localhost:8090/pagina.html</a>, pero no funciona.
Después de unas cuantas horas buscando por qué no funciona, al final con port forward funciona:
<div class="codigo">kubectl port-forward pod/<nombre pod> 8091:80</div>
</li>
<li>Para acceder a la aplicación contenorizada y kubernetizada:
<div ><a href="http://localhost:8091/pagina.html">http://localhost:8091/pagina.html</a></div>
</li>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-Z3xVfAQ8BoSlKYBgHFWYixLvaaC7msgmQKFUypPXMAGfcNVDLyb4JWliytdcdVGNIkRV1yGq9elAMXshbaWhx0GMnkFdVmUTdPf9ujlQH8zKyRSHqjGAFMyqYbDkXXVPINk8XmUNFQR73Z_wjYRCSFnXNhyiUXfRt6NAI35Bv84bXbUfSPn6WeOI0w/s1600/PantallaPagina.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" data-original-height="484" data-original-width="890" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-Z3xVfAQ8BoSlKYBgHFWYixLvaaC7msgmQKFUypPXMAGfcNVDLyb4JWliytdcdVGNIkRV1yGq9elAMXshbaWhx0GMnkFdVmUTdPf9ujlQH8zKyRSHqjGAFMyqYbDkXXVPINk8XmUNFQR73Z_wjYRCSFnXNhyiUXfRt6NAI35Bv84bXbUfSPn6WeOI0w/s1600/PantallaPagina.png"/></a></div>
<p>Minikube tiene un dashboard que da información sobre el entorno de ejecución y permite gestionarlo. Se arranca con minikube dashboard.</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJXxer7Xp0bQdxldc32alVfwhuizB1qfpbBvxC008YOAZ0tyYK1-6phroSjEVtuc7KQgYZz8u3mVEB-eyHSuVYAu6L4QsP4C_QVLljOW6-WndW_CchkBekomrPI7uVuGdyvkD5cv9qXhXaZ5dO27hDls2FYaLzoszT2vjywPXGB4BX1ceM3pmpwa3wcw/s1600/MinikubeDashboard.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" data-original-height="484" data-original-width="890" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJXxer7Xp0bQdxldc32alVfwhuizB1qfpbBvxC008YOAZ0tyYK1-6phroSjEVtuc7KQgYZz8u3mVEB-eyHSuVYAu6L4QsP4C_QVLljOW6-WndW_CchkBekomrPI7uVuGdyvkD5cv9qXhXaZ5dO27hDls2FYaLzoszT2vjywPXGB4BX1ceM3pmpwa3wcw/s1600/MinikubeDashboard.png"/></a></div>
<h3>Para terminar</h3>
<p>Este artículo explica en la práctica en qué consiste Kubernetes. La ventaja de utilizar una herramienta de este tipo es apoyar el despliegue de sistemas con software que ayude a los equipos de desarrollo y operaciones a dar mejor servicio a los usuarios. Automatizar el trabajo, si se hace correctamente ayuda a que las tareas repetitivas se hagan mejor y con menos errores.</p>
Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com1tag:blogger.com,1999:blog-895730532451445280.post-40705304024382029502022-02-13T11:31:00.000-08:002022-02-13T11:31:05.224-08:00¿Qué es LOW CODE?<p>Low Code es una corriente de desarrollo de software que ayuda a construir aplicaciones sin la necesidad de escribir código o escribiendo poco código.<br /><br />Hay numerosas herramientas que se publicitan como “Low Code” y que prometen:<br /><br /></p><ul style="text-align: left;"><li>Construir aplicaciones sin necesidad de ingenieros del software o expertos que dominen algún lenguaje de programación</li><li>Desarrollar apps para móviles, cloud y/o web </li><li>Crear aplicaciones haciendo “arrastrar y soltar”</li><li>Usar APIs REST sin necesidad de conocer los end-points o interfaz técnica</li><li>Conectar con bases de datos sin usar lenguajes técnicos: SQL o similares</li><li>Embellecer aplicaciones web o móviles sin saber html, css, ni javascript</li><li>Desarrollar flujos de trabajo adaptados a las necesidades del negocio</li><li>Utilizar plantillas preestablecidas como base de la creación de apps o flujos de trabajo</li></ul><p style="text-align: left;"><br />La corriente “Low Code” viene de antiguo. En 1968 en la universidad de Michigan se inició el proyecto ISDOS (Information System Design and Optimization System) que estaba enfocado en ayudar a los equipos de desarrollo durante las fases del desarrollo del software. Este proyecto iluminó a otros muchos que acabaron elaborando lo que se denominó herramientas CASE (Computer Aided Software Engineering). Estas herramientas ayudaban en el análisis y diseño permitiendo realizar gráficos del sistema a construir y documentar los elementos que lo componían. También basándose en distintos esqueletos, servían para generar código de forma automatizada. <br /><br />En la década de los 90 surgió la corriente de los lenguajes de programación basados en el paradigma de orientación a objetos (OO). A finales de los 90 con el auge de internet, estos lenguajes se llevaban toda la cuota de los nuevos desarrollos. Alentados por el éxito de las herramientas CASE del pasado, los expertos idearon un lenguaje de modelado específico para el desarrollo con lenguajes OO. Este lenguaje llamado UML (Unified Modeling Languaje) es un compendio de especificaciones para representar gráficamente todo lo que se puede desarrollar con un lenguaje OO. Partiendo de esta representación gráfica se crearon herramientas que generaban el código de los programas.<br /><br />Todas estas iniciativas se pueden considerar precursoras de Low Code puesto que finalmente conseguían que los programadores tuvieran que escribir menos código.<br /><br />El desarrollo de sistemas software consiste en su creación y posterior mantenimiento. Las empresas grandes y pequeñas invierten bastante dinero en el software que utilizan. Las herramientas de Low Code pretenden conseguir que esta inversión se minimice.<br /> <br />Veamos un ejemplo. Un departamento de ventas necesita hacer un resumen de los productos que se han vendido durante el año, se requiere elaborar un informe de los productos se han vendido mejor y han supuesto más ingresos para la compañía. Es necesario un resumen anual y un resumen mensual. Esta labor, antes de que existiesen las herramientas para hacer hojas de cálculo, requería un análisis en el que colaboraban un experto en ventas y un experto en desarrollo. Después un diseño para dar solución a lo analizado y para terminar una programación en algún lenguaje. Tras la puesta en marcha del sistema, viene el mantenimiento. ¿Qué pasa si el resumen además de mensual se requiere que sea semanal? Con las hojas de cálculo (Excel como máximo exponente) alguna persona del departamento de ventas, aprendió a diseñar, hacer cálculos y gráficos que resolvieron la situación con menos recursos (menos personas y menos tiempo).<br /><br />En este ejemplo la hoja de cálculo es una herramienta de Low Code. A los avezados empleados que aprendieron sin conocimientos de programación a construir estas hojas, en la terminología Low Code les llaman Citizen Developers. Yo lo traduciría como desarrolladores de a pie. Resuelven la papeleta sin conocimientos de lenguajes de programación, ni bases de datos, ni sistemas operativos.<br /><br />Estos Citizen Developers se suben al carro de los desarrolladores de software. Low Code dice que de esta forma se democratiza la construcción de software no necesitando grandes gurús de las tecnologías para construir sistemas de información.<br /><br />No obstante, no es oro todo lo que reluce. Hay que tener en cuenta que la gestión de los sistemas de información de una empresa no es algo sencillo. La complejidad es directamente proporcional al tamaño de la organización, pequeña poca complejidad, grande mucha. O sea, Low Code es una buena corriente que posibilita la creatividad software de más personas que no solo los expertos en tecnologías. Pero toda está creación de software debe estar orquestada de forma coherente y coordinada. De otra forma las empresas caminan hacia el caos. Le suena a alguien que un mismo dato que proviene de varias fuentes no sea igual. Por ejemplo las ventas en diciembre de un determinado producto, que tiene registradas Alberto y las que tiene registradas Ana.<br /><br />Pues eso, Low Code si pero con cabeza.<br /><br /></p>Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-37987041535683100042022-01-27T07:49:00.002-08:002022-03-14T10:59:32.841-07:00¿Qué es Docker y para qué sirve?<p>En informática un contenedor es una unidad estándar de software que empaqueta código y todas sus dependencias de tal forma que una aplicación se despliega y ejecuta rápida y fiablemente entre diferentes entornos. Un contenedor Docker es una imagen ligera, aislada y ejecutable que incluye todo lo necesario para ejecutar un software: código, herramientas, librerías y configuración.</p>
<p>Las imágenes de Docker llegan a ser contenedores cuando se ejecutan bajo el motor de Docker. Este motor está disponible para Linux, Windows y Mac. </p>
<p>La tecnología Docker se lanzó en 2013 como código abierto, enfocada en las necesidades de los desarrolladores y administradores de sistemas para ayudarles a separar las dependencias de la infraestructura. Esta tecnología ayuda a eliminar los problemas de instalar un software en distintos entornos y que las diferencias en la infraestructura produzcan fallos. De todos los desarrolladores y administradores es conocido el problema de desplegar el software desde los entornos de desarrollo a los de pruebas y producción.</p>
<p>El éxito que cosechó Docker en Linux condujo a la asociación con Microsoft que creó contenedores Docker para Windows. La tecnología Docker también está muy implantada en centros de datos, proveedores de servicios en la nube y frameworks serverless.</p>
<p>En una misma máquina pueden ejecutarse múltiples contenedores compartiendo el núcleo del sistema operativo, pero cada uno ejecutando los procesos de forma aislada en su propio espacio de nombres.</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjhbX-TTqI8LLRfoAFfg0ajeNFkz2GJoW75qOTgK-4T4wjN__xYdVsD1Z1Ca2glhB4tH5XJ0VKQmDkHPX2_9YoCOQLENx35zpXR8CneTHThTY7_yYRZPalLxK1HYRT1rQhSNgsvYqQvNt5ds_z3hZ7rUi0mrHZ3UKYvGGvaxA9yvmKI1Y98MQX8JleGtQ=s1198" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="957" data-original-width="1198" src="https://blogger.googleusercontent.com/img/a/AVvXsEjhbX-TTqI8LLRfoAFfg0ajeNFkz2GJoW75qOTgK-4T4wjN__xYdVsD1Z1Ca2glhB4tH5XJ0VKQmDkHPX2_9YoCOQLENx35zpXR8CneTHThTY7_yYRZPalLxK1HYRT1rQhSNgsvYqQvNt5ds_z3hZ7rUi0mrHZ3UKYvGGvaxA9yvmKI1Y98MQX8JleGtQ=s320"/></a></div>
<h2>Un ejemplo de uso de Docker</h2>
<ol>
<li>Instalación de Docker<br>
En <a href="https://hub.docker.com/" target="_blank">https://hub.docker.com/</a> se descarga el producto para el sistema operativo que se necesite: Linux, Windows o Mac, y se procede a su instalación. Normalmente tiene más que seguir las indicaciones (siguiente, siguiente, .. ya sabes)
</li>
<li>Descarga del container getting-started<br>
Tras la instalación se puede proceder a descargar y ejecutar el primer contenedor de muestra que proporciona Docker. Este contenedor incluye un servidor web Nginx y una web con la documentación de Docker. Para instalarlo en cada sistema operativo acceder al modo comando y escribir:<br>
<center><b>docker run -d -p 80:80 docker/getting-started</b></center><br>
este comando comprueba si tenemos esta imagen en nuestro ordenador, sino la tenemos la descarga (es nuestro caso, que acabamos de llegar a docker) y lo arranca.
</li>
<li>Ejecución de la aplicación del contenedor<br>
Lo que tenemos que hacer ahora el ir al navegador y escribir localhost. Esto arranca la web de documentación de Docker, que se ha instalado en el puerto 80 como si esta aplicación web de documentación y el servido Nginx estuviesen en nuestro ordenador.
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgIDQje-JKmCoov_YIgJBbFU1vrU37Ne1BOt2sGqiqxcsTa-QLz8uZr78UDIKozAUZ5azvfJd-5-eRZOm6ux0i8CFXGSaQ6qfzW9mbrVCWiK_y83Rfembbcl6U7H5vvYeSa-2TL6iILZAGdBhFHPL85U6U8wd7E3RaC98prSu65izvruJox8rEXwESoQg=s1910" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="600" data-original-height="1035" data-original-width="1910" src="https://blogger.googleusercontent.com/img/a/AVvXsEgIDQje-JKmCoov_YIgJBbFU1vrU37Ne1BOt2sGqiqxcsTa-QLz8uZr78UDIKozAUZ5azvfJd-5-eRZOm6ux0i8CFXGSaQ6qfzW9mbrVCWiK_y83Rfembbcl6U7H5vvYeSa-2TL6iILZAGdBhFHPL85U6U8wd7E3RaC98prSu65izvruJox8rEXwESoQg=s600"/></a></div>
Si miramos en detalle vemos la url escrita en el navegador y corresponde con nuestro ordenador.
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEiFTxSHJZjU5BY2w2s_YoD-DRuL0floPuU-DC7o2uwptHVvI_GXzrz-kEK3OJKc5V_fVPg6NX7rkSAUdGXrStEKoVLom9FBR4ldglR31oXGrwtp4zzTm7dU3SkL531eKv_3o_L8q5NuVupvL-JKaBC2HM-4i29NkrWS8wIWusVcdNef-Bh6DlVy6p_rtw=s1200" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="600" data-original-height="856" data-original-width="1200" src="https://blogger.googleusercontent.com/img/a/AVvXsEiFTxSHJZjU5BY2w2s_YoD-DRuL0floPuU-DC7o2uwptHVvI_GXzrz-kEK3OJKc5V_fVPg6NX7rkSAUdGXrStEKoVLom9FBR4ldglR31oXGrwtp4zzTm7dU3SkL531eKv_3o_L8q5NuVupvL-JKaBC2HM-4i29NkrWS8wIWusVcdNef-Bh6DlVy6p_rtw=s600"/></a></div>
</li>
</ol>
<h2>Uso de Docker desktop</h2>
<p>El Docker dektop se instaló con la instalación de docker y permite entre otras cosas gestionar las imágenes y contenedores.</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhstRL5jgv-KI4KMqId_GHkO5ftz_l2SryTqtyj1W2J1ufK-Tm-wwo3ek-9OLViYbgBcRBw8iG__cmAtb3dd6NFv-qiWxr8ajIq-usr9jSSZP-Wr8Y6575irpHxpEWjqZbA6PgIHXy7m3jRHlGdJk9Un17tKsGypeVlqsXkkwBa0eI-QHHofef6RkZ5Ug=s1920" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="600" data-original-height="1040" data-original-width="1920" src="https://blogger.googleusercontent.com/img/a/AVvXsEhstRL5jgv-KI4KMqId_GHkO5ftz_l2SryTqtyj1W2J1ufK-Tm-wwo3ek-9OLViYbgBcRBw8iG__cmAtb3dd6NFv-qiWxr8ajIq-usr9jSSZP-Wr8Y6575irpHxpEWjqZbA6PgIHXy7m3jRHlGdJk9Un17tKsGypeVlqsXkkwBa0eI-QHHofef6RkZ5Ug=s600"/></a></div>
Si miramos en detalle vemos que el contenedor que está arrancado es el getting-started que acabamos de instalar y usar, que se llama vigorous-hofstadter
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEguEgSsQ-D222OCuqUfsYYdG8lZ-ji-HfKtGd-biyGOOMZqMFux87zjgAxDFJzzzecLNvmSJxXSCJoiFTIuthsnrpq0a4v_BnRkvACaYDWowBWQfcK9f34ahXf5IZlMjwi8jsKTLbEeU10IcrJBEOQWTzJ6XT2xzImMZFkHF-MRHFFRklfUiKZ64ZjMIw=s1200" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="600" data-original-height="522" data-original-width="1200" src="https://blogger.googleusercontent.com/img/a/AVvXsEguEgSsQ-D222OCuqUfsYYdG8lZ-ji-HfKtGd-biyGOOMZqMFux87zjgAxDFJzzzecLNvmSJxXSCJoiFTIuthsnrpq0a4v_BnRkvACaYDWowBWQfcK9f34ahXf5IZlMjwi8jsKTLbEeU10IcrJBEOQWTzJ6XT2xzImMZFkHF-MRHFFRklfUiKZ64ZjMIw=s600"/></a></div>
<h2>Conclusión</h2>
<p>La tecnología de contenedores está actualmente en boga y ayuda a desarrollar y desplegar software evitando los quebraderos de cabeza que producen las dependencias entre unos paquetes software y otros.</p>
<h2>Referencia</h2>
<p>Para saber lo que es Docker está muy bien el post <a href="https://www.luisllamas.es/que-es-docker-y-como-usarlo/" target="_blank">https://www.luisllamas.es/que-es-docker-y-como-usarlo/</a></p>
Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-57500839166342122392022-01-07T11:51:00.000-08:002022-01-07T11:51:47.842-08:00Javascript: Para qué sirve AJAX (Asynchronous JavaScript And XML)<p>AJAX es el acrónimo de Asynchronous JavaScript And XML, y son un conjunto de técnicas ideadas alrededor de 2005 para mejorar el desarrollo de aplicaciones web. En ese momento las aplicaciones web eran mucho menos fléxibles que las aplicaciones de escritorio y con AJAX esta circunstancia cambió notablemente.</p>
<p>AJAX es un nombre para aglutinar varias tecnologías desarrolladas entorno a internet:</p><br>
<ul>
<li>XHTML+CSS</li>
<li>DOM</li>
<li>XMLHTTPRequest</li>
<li>Javascript</li>
<li>XML+XSLT (Actualmente en muchos casos JSON)</li>
</ul>
<p>De todas estas tecnologías el objeto JavaScript XMLHTTPRequest es el motor. Este objeto es capaz de hacer peticiones "no bloqueantes" al servidor. Esto mejora la experiencia de usuario, puesto que el navegador puede lanzar peticiones al servidor y mientras este realiza el proceso necesario para contestar a esa petición el navegador no ha de estar esperando. El navegador puede seguir recibiendo ordenes del usuario y encadenar peticiones que cuando van siendo respondidas incorporan datos que se actualizan en la página html ya cargada mediante funciones javascript que acceden a las etiquetas de la página con DOM.<p>
<p>Para explicar la diferencia de acceso al servidor con AJAX y sin AJAX se puede acceder a las siguientes grabaciones:</p>
<h3>Sin AJAX</h3>
<div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='600' height='498' src='https://www.blogger.com/video.g?token=AD6v5dyovvKvoIYBw8bRGZsPrFQSj_eu-zR3-MCy0qmYuCR7xXxTWNQirxnInygeFUMaM61ZMtGWa5wIv0gcK5DIbA' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div>
<h3>Con AJAX</h3>
<div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='600' height='498' src='https://www.blogger.com/video.g?token=AD6v5dyeuArR5NVJjrKneGBmtUCuGURBrvY8pkdL3MpdFJDJDaaJNiCXEOzK0-XKso-4n-X_2P0NxT8_KieX-RbctQ' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div>
<h2>Conclusión</h2>
<p>AJAX ha permitido desarrollar numerosas aplicaciones web, que tan útiles nos resultan en nuestro día a día. Eso si, no sin entrañar dificultades al tratar con las asincronías de XMLHTTPRequest y por lo tanto del API FETCH que tantos quebraderos de cabeza nos producen a los programadores.<p>Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-45125383745027241152021-12-26T14:56:00.001-08:002021-12-26T14:56:21.100-08:00La paradoja del circunnavegante<p>
Académicos sirios y franceses en el siglo XIII desarrollaron la "Paradoja del Circunnavegante" de la siguiente manera: supongamos que tres personas se reúnen en un lugar fijo: una se dirige hacia el oeste, otra sale hacia el este y la tercera permanece donde está, esperando a que las otras dos completen su viaje alrededor del mundo. A su regreso, el que viajó al oeste habrá perdido un día, mientras que el que viajó al este lo ganará.
</p>
<p>
Se demostró que esto era cierto en el primer viaje alrededor del mundo. En 1519 partió de Sanlucar de Barrameda una flota con Fernando de Magallanes al frente, el objetivo era abrir una ruta comercial hacia la isla de las especias por occidente. En aquellos tiempos las especias eran vitales para la conservación de los alimentos, la elaboración de medicamentos y para mejorar y/o potenciar el sabor de los alimentos que no siempre se comían en el mejor estado de conservación. El mercadeo de especias fue un negocio muy próspero durante 9 siglos. Acceder a este próspero negocio fue el motivo que llevo a la corona de España a financiar el viaje que fue el primero en el que varios hombres consiguieron dar una vuelta completa al globo terráqueo.
</p>
<p>
De la tripulación formaba parte Antonio Pigafetta que ocupaba el puesto de Sobresaliente. Este era un hombre cultivado que escribió un diario durante el viaje que fue de vital importancia para saber lo que acaeció durante los 3 años que duró la travesía. Entre todas las cosas para las que sirvió tal diario, una fue obtener una demostración práctica de la paradoja del circunnavegante. Cuando llegarón a Cabo Verde habían completado la vuelta completa a la tierra. Para Pigaffeta según sus anotaciones era miércoles 8 de julio de 1522 pero en Cabo Verde era 9 de julio jueves. Esto no se debía a un error en las anotaciones del diario.
</p>
<p>
Cuando se avanza hacia el oeste el sol sale y se pone cada vez más tarde, es decir los días son más largos que si estás en un punto fijo de la tierra. Concretamente por cada 111,32 km de avance el día se alarga 4 minutos. Teniendo en cuenta que el diámetro de la tierra es de 40.075 km, cuando has recorrido todo el diámetro de la tierra el sol saldrá: <b>4 minutos * (40.075 km / 111,32 km)</b> más tarde. Esto es igual a 1440 minutos más tarde, que son 24 horas. Si el sol sale 24 horas más tarde que cuando se comenzó el viaje, cuando se llega al destino se ha perdido 1 día completo.
</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEj1QAZ2caH5rukJArP88lBQWPV2J7qaepr8-o6MUh94aC0YB16tMTN_Tn5o8xb1IHXLljHF7o1XP4VNFVZgrfeqiwWdIYZbfzHUCZcvbZrWVSbVAcYEzLV3c_kxg4SA9JQyOPQ9fZ1Vp3VCzmIt1IhVJOHX0iKX-vr30MRGDBFD9GwANA82ilj21xkG5g=s686" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="685" data-original-width="686" src="https://blogger.googleusercontent.com/img/a/AVvXsEj1QAZ2caH5rukJArP88lBQWPV2J7qaepr8-o6MUh94aC0YB16tMTN_Tn5o8xb1IHXLljHF7o1XP4VNFVZgrfeqiwWdIYZbfzHUCZcvbZrWVSbVAcYEzLV3c_kxg4SA9JQyOPQ9fZ1Vp3VCzmIt1IhVJOHX0iKX-vr30MRGDBFD9GwANA82ilj21xkG5g=s320"/></a></div>
<p>
Si se viaja hacia el este lo que ocurre es que se gana 1 día puesto que el sol sale 24 horas antes ya que en este caso los días son más cortos. Julio Verne utilizó esta paradoja para su novela La Vuelta al Mundo en 80 días.
</p>
<p>
Desde 1884 durante una conferencia se convino crear la Línea Internacional de Cambio de Fecha. Esta línea sirve para que al ser traspasada los viajantes cambien de día y así uniformar las fechas de toda la humanidad aunque unos estén viajando hacia el este y otros hacia oeste.
</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgGnVDhIwO5k-18LkmXiars6xV6-7nWwGC4N47xHZZLTW2aheFxaRv3yLOHYIxrdAqrbsIdcohlKLX8EqTNmG0iFnJkYJLLMmY8j-NF2oyHT9POukWkn3VEwr4YHXWNTfe1QVppaxtITjOqSg1T5w61eFiV-1K2CtwFIpsEBV9wRwE3oJluYLk0hTy2Wg=s264" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="191" data-original-width="264" src="https://blogger.googleusercontent.com/img/a/AVvXsEgGnVDhIwO5k-18LkmXiars6xV6-7nWwGC4N47xHZZLTW2aheFxaRv3yLOHYIxrdAqrbsIdcohlKLX8EqTNmG0iFnJkYJLLMmY8j-NF2oyHT9POukWkn3VEwr4YHXWNTfe1QVppaxtITjOqSg1T5w61eFiV-1K2CtwFIpsEBV9wRwE3oJluYLk0hTy2Wg=s320"/></a></div>
Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-38212504419187583652021-12-01T09:01:00.001-08:002021-12-01T09:01:10.677-08:00Javascript: Ejemplos de Template Literal<p>Los Template Literal son plantillas que permiten intercalar expresiones dentro de una cadena, lo cual hace posible escribir cadenas sin tener que recurrir a la concatenación con el uso del operador +. También permiten escribir cadenas que tengan más de una línea, de nuevo sin recurrir al +. Además con los Templates etiquetados podemos incorporar procesamiento ad hoc. </p><h4 style="text-align: left;">Ejemplo simple <br /></h4><p>Un ejemplo muy simple de es:</p><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, 'Courier New', monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;"><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">miPrimerTemplateLiteral</span><span style="color: #d4d4d4;"> =</span><span style="color: #ce9178;"> `Este es un template literal`</span><span style="color: #d4d4d4;">;</span></div></div><p>aquí se está usando el caracter ` que es el que declara un template literal, pero no se está haciendo uso de ninguna de sus ventajas comparativas con las cadenas normales declaradas con ' o ".</p><h4 style="text-align: left;">Ejemplo de intercalado de expresiones <br /></h4><p>Un ejemplo que si saca partido a las posibilidades de un Template Literal sería:</p><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, 'Courier New', monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;"><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, 'Courier New', monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;"><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">nombre</span><span style="color: #d4d4d4;"> = </span><span style="color: #ce9178;">"Luis"</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">cantidad</span><span style="color: #d4d4d4;"> = </span><span style="color: #b5cea8;">23</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">precioUnitario</span><span style="color: #d4d4d4;">= </span><span style="color: #b5cea8;">105</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">iva</span><span style="color: #d4d4d4;"> = </span><span style="color: #b5cea8;">1.21</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">plantilla</span><span style="color: #d4d4d4;">=</span><span style="color: #ce9178;"> `Querido/a ${</span><span style="color: #9cdcfe;">nombre</span><span style="color: #ce9178;">},</span><span style="color: #d7ba7d;">\n</span><span style="color: #ce9178;">Espero que te encuentres bien.</span></div><div><span style="color: #ce9178;">Te recuerdo que el importe de la factura asciende a ${</span><span style="color: #9cdcfe;">cantidad</span><span style="color: #d4d4d4;">*</span><span style="color: #9cdcfe;">precioUnitario</span><span style="color: #d4d4d4;">*</span><span style="color: #9cdcfe;">iva</span><span style="color: #ce9178;">}`</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">plantilla</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #6a9955;">// Resultado: </span></div><div><span style="color: #6a9955;">// Querido/a Luis,</span></div><div><span style="color: #6a9955;">// Espero que te encuentres bien.</span></div><div><span style="color: #6a9955;">// Te recuerdo que el importe de la factura asciende a 2922.15</span></div></div></div><p>aquí el uso de ${} muestra como se pueden incluir expresiones dentro del literal que se sustituyen por su valor en tiempo de ejecución. También se puede observar cómo un Template Literal puede ocupar más de una línea y cómo puede incluir un salto de línea \n.<br /></p><h4 style="text-align: left;">Ejemplo de anidación</h4><p>Los template literal se pueden poner unos dentro de otros</p><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, 'Courier New', monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;"><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">color</span><span style="color: #d4d4d4;"> = </span><span style="color: #ce9178;">'rojas'</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">count</span><span style="color: #d4d4d4;"> = </span><span style="color: #b5cea8;">3</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">message</span><span style="color: #d4d4d4;"> =</span><span style="color: #ce9178;"> `Tengo ${</span><span style="color: #9cdcfe;">color</span><span style="color: #ce9178;"> </span><span style="color: #d4d4d4;">?</span><span style="color: #ce9178;"> `${</span><span style="color: #9cdcfe;">count</span><span style="color: #ce9178;">} manzanas ${</span><span style="color: #9cdcfe;">color</span><span style="color: #ce9178;">}` </span><span style="color: #d4d4d4;">:</span><span style="color: #ce9178;"> `${</span><span style="color: #9cdcfe;">count</span><span style="color: #ce9178;">} manzanas`} `</span><span style="color: #d4d4d4;">; </span><span style="color: #6a9955;">// Noncompliant; nested template strings not easy to read</span></div><div><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">'Mesagge</span><span style="color: #d4d4d4;"> </span><span style="color: #ce9178;">'</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">message</span><span style="color: #d4d4d4;">)</span></div><div><span style="color: #6a9955;">// Resultado: Mesagge Tengo 3 manzanas rojas</span></div></div><p>No obstante esta forma de codificación está desaconsejada por SonarQube, herramienta que vela por la calidad del código. El motivo es la poca legibilidad del mismo, aconsejando esta herramienta codificar de la siguiente manera</p><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, 'Courier New', monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;"><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">apples</span><span style="color: #d4d4d4;"> = </span><span style="color: #9cdcfe;">color</span><span style="color: #d4d4d4;"> ?</span><span style="color: #ce9178;"> `${</span><span style="color: #9cdcfe;">count</span><span style="color: #ce9178;">} manzanas ${</span><span style="color: #9cdcfe;">color</span><span style="color: #ce9178;">}`</span><span style="color: #d4d4d4;"> :</span><span style="color: #ce9178;"> `${</span><span style="color: #9cdcfe;">count</span><span style="color: #ce9178;">} manzanas`</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #9cdcfe;">message</span><span style="color: #d4d4d4;"> =</span><span style="color: #ce9178;"> `Tengo ${</span><span style="color: #9cdcfe;">apples</span><span style="color: #ce9178;">}`</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">'Mesagge</span><span style="color: #d4d4d4;"> </span><span style="color: #ce9178;">'</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">message</span><span style="color: #d4d4d4;">)</span></div><div><span style="color: #6a9955;">// Resultado: Mesagge Tengo 3 manzanas rojas</span></div></div><div style="text-align: left;"> </div><h4 style="text-align: left;">Ejemplo de templates etiquetados</h4><p>Un tTmplate se puede etiquetar con el nombre de una función. Esta recibe los textos y expresiones del Template Literal pudiendo procesarlo como se requiera.</p><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, 'Courier New', monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;"><div><span style="color: #569cd6;">function</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">templatetag</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">literales</span><span style="color: #d4d4d4;">, ...</span><span style="color: #9cdcfe;">expresiones</span><span style="color: #d4d4d4;">){</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">'lit</span><span style="color: #d4d4d4;"> </span><span style="color: #ce9178;">'</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">literales</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">'exp</span><span style="color: #d4d4d4;"> </span><span style="color: #ce9178;">'</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">expresiones</span><span style="color: #d4d4d4;">)</span></div><div><span style="color: #d4d4d4;">}</span></div><br /><div><span style="color: #dcdcaa;">templatetag</span><span style="color: #ce9178;">`amigo ${</span><span style="color: #b5cea8;">2</span><span style="color: #d4d4d4;">+</span><span style="color: #b5cea8;">2</span><span style="color: #ce9178;">} mio`</span></div><div><span style="color: #6a9955;">// Resultado; lit [ 'amigo ', ' mio' ] exp [ 4 ]</span></div></div><p>Esta característica de los Template Literal permite procesar su contenido según se requiera, por ejemplo<br /></p><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, 'Courier New', monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;"><div><span style="color: #569cd6;">function</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">priceonSeason</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">literales</span><span style="color: #d4d4d4;">, ...</span><span style="color: #9cdcfe;">expresiones</span><span style="color: #d4d4d4;">) {</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">precio</span><span style="color: #d4d4d4;"> = </span><span style="color: #b5cea8;">100</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">if</span><span style="color: #d4d4d4;"> (</span><span style="color: #9cdcfe;">literales</span><span style="color: #d4d4d4;">[</span><span style="color: #b5cea8;">1</span><span style="color: #d4d4d4;">] == </span><span style="color: #ce9178;">' diciembre'</span><span style="color: #d4d4d4;">) </span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">return</span><span style="color: #ce9178;"> `Su reserva para temporada baja ha sido confirmada. </span></div><div><span style="color: #ce9178;"> ${</span><span style="color: #9cdcfe;">expresiones</span><span style="color: #ce9178;">[</span><span style="color: #b5cea8;">0</span><span style="color: #ce9178;">]} personas por un importe de ${</span><span style="color: #9cdcfe;">precio</span><span style="color: #d4d4d4;">*</span><span style="color: #b5cea8;">0.90</span><span style="color: #ce9178;">}`</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">else</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">return</span><span style="color: #ce9178;"> `Su reserva para temporada alta ha sido confirmada. </span></div><div><span style="color: #ce9178;"> ${</span><span style="color: #9cdcfe;">expresiones</span><span style="color: #ce9178;">[</span><span style="color: #b5cea8;">0</span><span style="color: #ce9178;">]} personas por un importe de ${</span><span style="color: #9cdcfe;">precio</span><span style="color: #ce9178;">}`</span></div><div><span style="color: #d4d4d4;">}</span></div><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">pax</span><span style="color: #d4d4d4;"> = </span><span style="color: #b5cea8;">2</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">respond</span><span style="color: #d4d4d4;"> =</span><span style="color: #ce9178;"> </span><span style="color: #dcdcaa;">priceonSeason</span><span style="color: #ce9178;">`Reserva de plaza para ${</span><span style="color: #9cdcfe;">pax</span><span style="color: #ce9178;">} diciembre`</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'Ejemplo etiquetado'</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">respond</span><span style="color: #d4d4d4;">)</span></div><div><span style="color: #6a9955;">// Resultado</span></div><div><span style="color: #6a9955;">// Ejemplo etiquetado Su reserva para temporada baja ha sido confirmada. </span></div><div><span style="color: #6a9955;">// 2 personas por un importe de 90</span></div></div><div style="text-align: left;"> </div><h4 style="text-align: left;">Conclusión</h4><p>Los Template Literal son cadenas de caracteres con características avanzadas que proporcionan medios al programador para trabajar con cadenas de caracteres de una muy versatil.<br /></p>Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-78059882028942597952021-11-07T11:34:00.001-08:002021-11-07T11:34:47.573-08:00Javascript: Ejemplos de uso del operador spread<p>El operador spread permite manejar elementos considerados iterables como son arrays(un array tiene/itera elementos), strings(tiene/itera caracteres) u objetos(tiene/itera pares clave-valor) sin necesidad de preparar un algoritmo cíclico o de bucle. </p><p>Con spread se puede: </p><ul style="text-align: left;"><li>En llamadas a funciones, que arrays o strings expandan sus elementos. </li><li>Operar entre arrays, el operador expande sus elementos. Se pueden copiar, mezclar, intercalar.</li><li>Operar con objetos spread expande los pares clave-valor. Lo mismo que los arrays </li></ul><h4 style="text-align: left;">Ejemplos básicos</h4><h4 style="text-align: left;"><br /></h4><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, 'Courier New', monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;"><div><span style="color: #6a9955;">// expande el string en sus 3 caracteres</span></div><div><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">'String expandido:</span><span style="color: #d4d4d4;"> </span><span style="color: #ce9178;">'</span><span style="color: #d4d4d4;">, ...</span><span style="color: #ce9178;">"abc"</span><span style="color: #d4d4d4;">); </span></div><div><span style="color: #6a9955;">// expande el array en sus 4 elementos</span></div><div><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">'Array expandido:</span><span style="color: #d4d4d4;"> </span><span style="color: #ce9178;">'</span><span style="color: #d4d4d4;">, ...[</span><span style="color: #b5cea8;">1</span><span style="color: #d4d4d4;">,</span><span style="color: #b5cea8;">2</span><span style="color: #d4d4d4;">,</span><span style="color: #b5cea8;">3</span><span style="color: #d4d4d4;">,</span><span style="color: #b5cea8;">4</span><span style="color: #d4d4d4;">]); </span></div><div><span style="color: #6a9955;">// Expande el primer objeto y le añade el par clave-valor masattr: 'def'</span></div><div><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">'Objeto expandido:</span><span style="color: #d4d4d4;"> </span><span style="color: #ce9178;">'</span><span style="color: #d4d4d4;">, {...{</span><span style="color: #9cdcfe;">id</span><span style="color: #d4d4d4;">: </span><span style="color: #b5cea8;">1</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">desc</span><span style="color: #d4d4d4;">:</span><span style="color: #ce9178;">'abc'</span><span style="color: #d4d4d4;">}, </span><span style="color: #9cdcfe;">masattr</span><span style="color: #d4d4d4;">: </span><span style="color: #ce9178;">'def'</span><span style="color: #d4d4d4;"> }); </span></div><div><span style="color: #6a9955;">// Expande los arrays y crea uno nuevo con los elementos de los dos</span></div><div><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">'Une dos arrays:</span><span style="color: #d4d4d4;"> </span><span style="color: #ce9178;">'</span><span style="color: #d4d4d4;">,[...[</span><span style="color: #b5cea8;">1</span><span style="color: #d4d4d4;">,</span><span style="color: #b5cea8;">2</span><span style="color: #d4d4d4;">,</span><span style="color: #b5cea8;">3</span><span style="color: #d4d4d4;">,</span><span style="color: #b5cea8;">4</span><span style="color: #d4d4d4;">],...[</span><span style="color: #b5cea8;">5</span><span style="color: #d4d4d4;">,</span><span style="color: #b5cea8;">6</span><span style="color: #d4d4d4;">]])</span></div><br /><div><span style="color: #6a9955;">// String expandido: a b c</span></div><div><span style="color: #6a9955;">// Array expandido: 1 2 3 4</span></div><div><span style="color: #6a9955;">// Objeto expandido: { id: 1, desc: 'abc', masattr: 'def' }</span></div><div><span style="color: #6a9955;">// Une dos arrays: [ 1, 2, 3, 4, 5, 6 ]</span></div></div><h4 style="text-align: left;"> </h4><h4 style="text-align: left;">Otros ejemplos</h4><p> En el siguiente ejemplo se intercalas los elementos de un array en otro</p><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, 'Courier New', monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;"><div><span style="color: #6a9955;">// Spread en array </span></div><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">otrosIdiomas</span><span style="color: #d4d4d4;"> = [</span><span style="color: #ce9178;">'inglés'</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">'aleman'</span><span style="color: #d4d4d4;">];</span></div><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">idiomasHablados</span><span style="color: #d4d4d4;"> = [</span><span style="color: #ce9178;">'español'</span><span style="color: #d4d4d4;">, ...</span><span style="color: #9cdcfe;">otrosIdiomas</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">'frances'</span><span style="color: #d4d4d4;">];</span></div><div><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'Ver idiomasHablados:</span><span style="color: #d4d4d4;"> </span><span style="color: #ce9178;">'</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">idiomasHablados</span><span style="color: #d4d4d4;">)</span></div><div><span style="color: #6a9955;">// Ver idiomasHablados: [ 'español', 'inglés', 'aleman', 'frances' ]</span></div></div><p>En el siguiente ejemplo se copia un array en otro. La copia es poco profunda (shallow), es decir el array original es totalmente independiente de nuevo obtenido con la copia.</p><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, 'Courier New', monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;"><div><span style="color: #6a9955;">// Copiar array como arr.slice()</span></div><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">numeros1</span><span style="color: #d4d4d4;"> = [</span><span style="color: #b5cea8;">1</span><span style="color: #d4d4d4;">, </span><span style="color: #b5cea8;">2</span><span style="color: #d4d4d4;">, </span><span style="color: #b5cea8;">3</span><span style="color: #d4d4d4;">];</span></div><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">numeros2</span><span style="color: #d4d4d4;"> = [...</span><span style="color: #9cdcfe;">numeros1</span><span style="color: #d4d4d4;">]; </span></div><div><span style="color: #9cdcfe;">numeros2</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">push</span><span style="color: #d4d4d4;">(</span><span style="color: #b5cea8;">4</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'numeros1 y numeros2:</span><span style="color: #d4d4d4;"> </span><span style="color: #ce9178;">'</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">numeros1</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">numeros2</span><span style="color: #d4d4d4;">) </span></div><div><span style="color: #6a9955;">// numeros1 y numeros2: [ 1, 2, 3 ] [ 1, 2, 3, 4 ]</span></div></div><p>En el siguiente ejemplo el array es pasado a una función, el operador spread expande el array y se convierten en los argumentos de la función llamada.</p><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, 'Courier New', monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;"><div><span style="color: #6a9955;">//Spread en llamadas a funciones</span></div><div><span style="color: #569cd6;">function</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">miFuncion</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">a1</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">a2</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">a3</span><span style="color: #d4d4d4;">) { </span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'Argumentos:</span><span style="color: #d4d4d4;"> </span><span style="color: #ce9178;">'</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">a1</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">a2</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">a3</span><span style="color: #d4d4d4;">)</span></div><div><span style="color: #d4d4d4;">}</span></div><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">argumentos</span><span style="color: #d4d4d4;"> = [</span><span style="color: #b5cea8;">0</span><span style="color: #d4d4d4;">, </span><span style="color: #b5cea8;">1</span><span style="color: #d4d4d4;">, </span><span style="color: #b5cea8;">2</span><span style="color: #d4d4d4;">];</span></div><div><span style="color: #dcdcaa;">miFuncion</span><span style="color: #d4d4d4;">(...</span><span style="color: #9cdcfe;">argumentos</span><span style="color: #d4d4d4;">);</span></div></div><p>En el siguiente ejemplo se copian y mezclan objetos siendo de nuevo una copia poco profunda.</p><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, 'Courier New', monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;"><div><span style="color: #6a9955;">// Con objetos</span></div><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">objeto1</span><span style="color: #d4d4d4;"> = { </span><span style="color: #9cdcfe;">desc</span><span style="color: #d4d4d4;">: </span><span style="color: #ce9178;">'ob1'</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">p1</span><span style="color: #d4d4d4;">: </span><span style="color: #b5cea8;">1</span><span style="color: #d4d4d4;"> };</span></div><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">objeto2</span><span style="color: #d4d4d4;"> = { </span><span style="color: #9cdcfe;">desc</span><span style="color: #d4d4d4;">: </span><span style="color: #ce9178;">'ob2'</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">p2</span><span style="color: #d4d4d4;">: </span><span style="color: #b5cea8;">2</span><span style="color: #d4d4d4;"> };</span></div><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">objetoCopiado</span><span style="color: #d4d4d4;"> = { ...</span><span style="color: #9cdcfe;">objeto1</span><span style="color: #d4d4d4;"> };</span></div><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">objetoMezclado</span><span style="color: #d4d4d4;"> = { ...</span><span style="color: #9cdcfe;">objeto1</span><span style="color: #d4d4d4;">, ...</span><span style="color: #9cdcfe;">objeto2</span><span style="color: #d4d4d4;"> };</span></div><div><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'Objetos copiado y mezclado:</span><span style="color: #d4d4d4;"> </span><span style="color: #ce9178;">'</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">objetoCopiado</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">objetoMezclado</span><span style="color: #d4d4d4;">)</span></div><div><span style="color: #6a9955;">// Objetos copiado y mezclado: { desc: 'ob1', p1: 1 } { desc: 'ob2', p1: 1, p2: 2 }</span></div></div><h4 style="text-align: left;"> </h4><h4 style="text-align: left;">Conclusión</h4><p>El operador spread facilita las tareas del desarrollador cuando se trata de realizar ciertas operaciones con objetos iterables: array, strings y objetos.<br /></p><p><br /></p><p> <br /></p>Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-59505709230347269102021-11-01T10:30:00.003-07:002021-11-01T12:50:58.039-07:00JavaScript: Ejemplo del método Promise.all()<p>Este método es útil cuando se han creado varias promesas y es necesario realizar una operación solo cuando se hayan resuelto todas.<br /><br />El método Promise.all() toma un array de promesas como entrada y devuelve una sola promesa que se resuelve con un array que contiene el resultado de las promesas de entrada. La promesa devuelta se resolverá sólo si todas las promesas de entrada se resuelven se rechazará si alguna es rechazada. El rechazo se resolverá con el mensaje de error de la primera promesa rechazada.</p><h3 style="text-align: left;">Ejemplo</h3><div style="text-align: left;">En este ejemplo se crean 2 promesas que devuelven los resultados en momentos distintos. Una de ellas devuelve el resultado en 2 segundos y la otra en 1 segundo. Con el método all(), se consigue que el resultado no se procese hasta que hayan terminado las dos promesas. <br /></div><div style="text-align: left;"><br /></div><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, 'Courier New', monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;"><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">datosA</span><span style="color: #d4d4d4;"> = </span><span style="color: #569cd6;">new</span><span style="color: #d4d4d4;"> </span><span style="color: #4ec9b0;">Promise</span><span style="color: #d4d4d4;">((</span><span style="color: #dcdcaa;">resolve</span><span style="color: #d4d4d4;">, </span><span style="color: #dcdcaa;">reject</span><span style="color: #d4d4d4;">) </span><span style="color: #569cd6;">=></span></div><div><span style="color: #d4d4d4;"> {</span><span style="color: #dcdcaa;">setTimeout</span><span style="color: #d4d4d4;">(()</span><span style="color: #569cd6;">=></span><span style="color: #d4d4d4;"> (</span><span style="color: #dcdcaa;">resolve</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">"datos de A"</span><span style="color: #d4d4d4;">), </span><span style="color: #b5cea8;">2000</span><span style="color: #d4d4d4;">))});</span></div><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">datosB</span><span style="color: #d4d4d4;"> = </span><span style="color: #569cd6;">new</span><span style="color: #d4d4d4;"> </span><span style="color: #4ec9b0;">Promise</span><span style="color: #d4d4d4;">((</span><span style="color: #dcdcaa;">resolve</span><span style="color: #d4d4d4;">, </span><span style="color: #dcdcaa;">reject</span><span style="color: #d4d4d4;">) </span><span style="color: #569cd6;">=></span><span style="color: #d4d4d4;"> </span></div><div><span style="color: #d4d4d4;"> {</span><span style="color: #dcdcaa;">setTimeout</span><span style="color: #d4d4d4;">(()</span><span style="color: #569cd6;">=></span><span style="color: #d4d4d4;"> (</span><span style="color: #dcdcaa;">resolve</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">"datos de B"</span><span style="color: #d4d4d4;">), </span><span style="color: #b5cea8;">1000</span><span style="color: #d4d4d4;">))});</span></div><br /><div><span style="color: #4ec9b0;">Promise</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">all</span><span style="color: #d4d4d4;">([</span><span style="color: #9cdcfe;">datosA</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">datosB</span><span style="color: #d4d4d4;">]).</span><span style="color: #dcdcaa;">then</span><span style="color: #d4d4d4;">((</span><span style="color: #9cdcfe;">result</span><span style="color: #d4d4d4;">) </span><span style="color: #569cd6;">=></span><span style="color: #d4d4d4;"> </span></div><div><span style="color: #d4d4d4;"> {</span><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">"datosAyB</span><span style="color: #d4d4d4;"> </span><span style="color: #ce9178;">"</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">result</span><span style="color: #d4d4d4;">)})</span></div><br /><div><span style="color: #6a9955;">// RESULTADO: datosAyB [ 'datos de A', 'datos de B' ]</span><br /></div></div><h3 style="text-align: left;">Otro ejemplo</h3><p>En este ejemplo se requiere rellenar el contenido de las variables datosA y datosB. Las funciones de relleno son promesas que se resuelven de nuevo en tiempos distintos, 1 o 2 segundos. Con el método all() se consigue sincronizar las funciones de rellenado y solo se muestra el contenido de las variables cuando están ámbas rellenas.<br /></p><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, 'Courier New', monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;"><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">datosA</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">datosB</span><span style="color: #d4d4d4;">;</span></div><br /><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">rellenadatosA</span><span style="color: #d4d4d4;"> = </span><span style="color: #569cd6;">new</span><span style="color: #d4d4d4;"> </span><span style="color: #4ec9b0;">Promise</span><span style="color: #d4d4d4;">((</span><span style="color: #dcdcaa;">resolve</span><span style="color: #d4d4d4;">, </span><span style="color: #dcdcaa;">reject</span><span style="color: #d4d4d4;">) </span><span style="color: #569cd6;">=></span><span style="color: #d4d4d4;"> </span></div><div><span style="color: #d4d4d4;"> {</span><span style="color: #dcdcaa;">setTimeout</span><span style="color: #d4d4d4;">(()</span><span style="color: #569cd6;">=></span><span style="color: #d4d4d4;"> </span></div><div><span style="color: #d4d4d4;"> {</span><span style="color: #9cdcfe;">datosA</span><span style="color: #d4d4d4;">=</span><span style="color: #ce9178;">"datos A"</span><span style="color: #d4d4d4;">; </span><span style="color: #dcdcaa;">resolve</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">datosA</span><span style="color: #d4d4d4;">)}, </span><span style="color: #b5cea8;">2000</span><span style="color: #d4d4d4;">)});</span></div><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">rellenadatosB</span><span style="color: #d4d4d4;"> = </span><span style="color: #569cd6;">new</span><span style="color: #d4d4d4;"> </span><span style="color: #4ec9b0;">Promise</span><span style="color: #d4d4d4;">((</span><span style="color: #dcdcaa;">resolve</span><span style="color: #d4d4d4;">, </span><span style="color: #dcdcaa;">reject</span><span style="color: #d4d4d4;">) </span><span style="color: #569cd6;">=></span><span style="color: #d4d4d4;"> </span></div><div><span style="color: #d4d4d4;"> {</span><span style="color: #dcdcaa;">setTimeout</span><span style="color: #d4d4d4;">(() </span><span style="color: #569cd6;">=></span><span style="color: #d4d4d4;"> </span></div><div><span style="color: #d4d4d4;"> {</span><span style="color: #9cdcfe;">datosB</span><span style="color: #d4d4d4;">=</span><span style="color: #ce9178;">"datos B"</span><span style="color: #d4d4d4;">; </span><span style="color: #dcdcaa;">resolve</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">datosB</span><span style="color: #d4d4d4;">)}, </span><span style="color: #b5cea8;">1000</span><span style="color: #d4d4d4;">)});</span></div><br /><div><span style="color: #4ec9b0;">Promise</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">all</span><span style="color: #d4d4d4;">([</span><span style="color: #9cdcfe;">rellenadatosA</span><span style="color: #d4d4d4;">]).</span><span style="color: #dcdcaa;">then</span><span style="color: #d4d4d4;">(() </span><span style="color: #569cd6;">=></span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">"datosAyB</span><span style="color: #d4d4d4;"> </span><span style="color: #ce9178;">"</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">datosA</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">datosB</span><span style="color: #d4d4d4;">));</span></div><br /><div><span style="color: #6a9955;">// datosAyB datos A datos B</span></div></div><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, 'Courier New', monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;"></div><p>Espero que sea de ayuda. Si quedan dudas, dejadlas en comentarios. </p><p>Chao<br /></p><p><br /></p>Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-57015885327497588962021-10-28T09:59:00.003-07:002021-10-28T10:04:38.073-07:00Javascript: Otro ejemplo sencillo de callback, promise y async/await<p>En los comienzos de internet los sitios web ofrecían datos estáticos en páginas HTML. Actualmente las aplicaciones web son interactivas y dinámicas y se ha incrementado la necesidad de hacer operaciones como peticiones en la red para recuperar datos a través de un API. Para manejar estas operaciones en JavaScript, un desarrollador debe usar técnicas asíncronas de programación.
JavasScript es un lenguaje de un solo hilo(thread) con un
modelo de ejecución síncrono que procesa una operación trás otra y solo puede procesar una instrucción al mismo tiempo. Sin embargo, una acción como pedir datos a un API puede consumir una cantidad tiempo grande dependiendo de la velocidad de la red, la cantidad de datos solicitados y otros factores. Si la llamada a la API se hace de forma síncrona, el buscador no será capaz de manejar las acciones del usuario como hacer scrolling o pulsar un botón hasta que la operación se haya completado. Esto se conoce como blocking.
Para evitar que se produzca "blocking", los entornos de browser (Chrome, Firefox, Edge, Opera, Safari, etc.) han desarrollado Web APIs para que desde JavaScript los accesos puedan ser asíncronos, de tal manera que se pueden ejecutar en paralelo con otras operaciones. Esto previene el "blocking" porque el usuario puede seguir interactuando con la página mientras la petición asíncrona se está procesando.
Cómo desarrollador de JavaScript es necesario saber como trabajar con las Web APis asíncronas y manejar los datos recibidos de ellas. En este ejemplo, vamos a trabajar con varías técnicas de tratamiento de la asíncronia: callbacks, promesas y async/await. </p><h3 style="text-align: left;">EJEMPLO </h3><div style="text-align: left;">Es un módulo que en la función Hello() llama a una función asíncrona setTimeout(). Esta función le asigna el valor 'Buenos días' a la variable greetings al cabo de 1000 milisegundos(1 segundo).
La función setTimeout() es asíncrona y no bloqueante porque se lanza su ejecución y el programa continua ejecutando las siguientes instrucciones sin esperar a que setTimeout haya terminado. ¿Qué se puede hacer para controlar el orden en que se ejecutan las sentencias tras la llamada a setTimeout? ¿Qué pasa si setTimeout obtiene algún dato que necesitamos para tomar una decisión en el programa o para mostrarlo en la consola? Veamos: </div><div style="text-align: left;"> </div><div style="text-align: left;"><h4 style="text-align: left;">No se maneja la asincronía (sincronizar1.js)</h4></div><div style="text-align: left;">Cuando se hace el console.log de la variable greetings esta está vacía. La sentencia de asignación se ejecutará después de que se hayan hecho os console logs.</div><div style="text-align: left;"> </div><div style="text-align: left;"><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;"><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">greetings</span><span style="color: #d4d4d4;"> = </span><span style="color: #ce9178;">''</span><span style="color: #d4d4d4;">;</span></div><br /><div><span style="color: #569cd6;">function</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">hello</span><span style="color: #d4d4d4;">() { </span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">setTimeout</span><span style="color: #d4d4d4;">(()</span><span style="color: #569cd6;">=></span><span style="color: #d4d4d4;">{</span><span style="color: #9cdcfe;">greetings</span><span style="color: #d4d4d4;"> = </span><span style="color: #ce9178;">'Buenos Días'</span><span style="color: #d4d4d4;">;}, </span><span style="color: #b5cea8;">1000</span><span style="color: #d4d4d4;">); </span></div><div><span style="color: #d4d4d4;">}</span></div><br /><div><span style="color: #569cd6;">function</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">synchronize</span><span style="color: #d4d4d4;">(){</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[36m%s</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[0m'</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">'1- Empieza synchronize'</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">hello</span><span style="color: #d4d4d4;">();</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'2- greetings está vacio'</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">greetings</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[36m%s</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[0m'</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">'3- Acaba synchronize'</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;">}</span></div><br /><div><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[31m%s</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[0m'</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">'0- Empieza módulo'</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #dcdcaa;">synchronize</span><span style="color: #d4d4d4;">();</span></div><div><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[31m%s</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[0m'</span><span style="color: #d4d4d4;">,</span><span style="color: #ce9178;">'4- Acaba módulo'</span><span style="color: #d4d4d4;">);</span></div></div> </div><div style="text-align: left;">siendo el resultado de la ejecución</div><div style="text-align: left;"><br /> <br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYHDNb6k_PjhpP8ONPxR-NLK8pCZ3LwXuIgpsCCg0eq5RMHX_guLK3iXv5O2L-tyw_PnWSPtbAtZZu13IKXm6K4_e27BvrOOVoDiGExRnICl6500aeBUhGZWGJtgeXWvWi-5ghsW3egemK/s644/ejecucion1.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="130" data-original-width="644" height="65" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYHDNb6k_PjhpP8ONPxR-NLK8pCZ3LwXuIgpsCCg0eq5RMHX_guLK3iXv5O2L-tyw_PnWSPtbAtZZu13IKXm6K4_e27BvrOOVoDiGExRnICl6500aeBUhGZWGJtgeXWvWi-5ghsW3egemK/s320/ejecucion1.png" width="320" /></a></div><p></p><h4 style="text-align: left;">Se maneja la asincronía con callback (sincronizar2.js)</h4><p>La función hello(f) tiene un parámetro que representa a una función. Cuando se llama a la función hello se envia como parametro el nombre de la función que muestra el contenido de greetings, así hello(f) puede llamar a la función después de que el valor 'Buenos Dias' se haya asignado a greetings. De esta manera el algoritmo programado se ocupa de que la variable greetings esté rellena antes de ser mostrada.</p><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;"><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">greetings</span><span style="color: #d4d4d4;"> = </span><span style="color: #ce9178;">''</span><span style="color: #d4d4d4;">;</span></div><br /><div><span style="color: #569cd6;">function</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">hello</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">fdespues</span><span style="color: #d4d4d4;">) { </span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">setTimeout</span><span style="color: #d4d4d4;">(()</span><span style="color: #569cd6;">=></span><span style="color: #d4d4d4;">{</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">greetings</span><span style="color: #d4d4d4;"> = </span><span style="color: #ce9178;">'Buenos Días'</span><span style="color: #d4d4d4;">, </span><span style="color: #dcdcaa;">fdespues</span><span style="color: #d4d4d4;">()}, </span><span style="color: #b5cea8;">1000</span><span style="color: #d4d4d4;"> ); </span></div><div><span style="color: #d4d4d4;">}</span></div><br /><div><span style="color: #569cd6;">function</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">mostrar</span><span style="color: #d4d4d4;">(){</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'2-'</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">greetings</span><span style="color: #d4d4d4;">)</span></div><div><span style="color: #d4d4d4;">}</span></div><br /><div><span style="color: #569cd6;">function</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">synchronize</span><span style="color: #d4d4d4;">(){</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[36m%s</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[0m'</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">'1- Empieza synchronize'</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">hello</span><span style="color: #d4d4d4;">(</span><span style="color: #dcdcaa;">mostrar</span><span style="color: #d4d4d4;">); </span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[36m%s</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[0m'</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">'3- Acaba synchronize'</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;">}</span></div><br /><div><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[31m%s</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[0m'</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">'0- Empieza módulo'</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #dcdcaa;">synchronize</span><span style="color: #d4d4d4;">();</span></div><div><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[31m%s</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[0m'</span><span style="color: #d4d4d4;">,</span><span style="color: #ce9178;">'4- Acaba módulo'</span><span style="color: #d4d4d4;">);</span></div></div><p> siendo el resultado de la ejecución</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDLtEwYzLtDxu43W_b4IoFf5PJsqO12nNWOvdd6sMuee7Mf89gjzisj-xj76_cVkrWN88IVSI0DJ-rW4_E0xlw-A6iTZU5Ze-ciArDQAigerPhDUB4jusxN7jPXQTQEdpV8TmHtM6dsq6U/s651/ejecucion2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="129" data-original-width="651" height="63" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDLtEwYzLtDxu43W_b4IoFf5PJsqO12nNWOvdd6sMuee7Mf89gjzisj-xj76_cVkrWN88IVSI0DJ-rW4_E0xlw-A6iTZU5Ze-ciArDQAigerPhDUB4jusxN7jPXQTQEdpV8TmHtM6dsq6U/s320/ejecucion2.png" width="320" /></a></div><br /><p></p><h4 style="text-align: left;"> Se maneja la asincronía con Promise y then() (sincronizar3.js)</h4><p> El objeto Promise se ha diseñado para tratar con funciones asíncronas y dispone de dos parámetros: resolve que representa a una función que indica que todo ha ido bien y la función asíncrona ha terminado con éxito y reject que indica que ha habido algún error. En este módulo la función hello() devuelve una promesa y con el método then() se consigue que el console.log de la variable no se lleve a cabo hasta que la variable tiene el valor asignado. El metodo then() ejecuta la función especificada cuando la promesa ha efectuado un resolve().</p><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;"><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">greetings</span><span style="color: #d4d4d4;"> = </span><span style="color: #ce9178;">''</span><span style="color: #d4d4d4;">;</span></div><br /><div><span style="color: #569cd6;">function</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">hello</span><span style="color: #d4d4d4;">() { </span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">return</span><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">new</span><span style="color: #d4d4d4;"> </span><span style="color: #4ec9b0;">Promise</span><span style="color: #d4d4d4;">((</span><span style="color: #dcdcaa;">resolve</span><span style="color: #d4d4d4;">, </span><span style="color: #dcdcaa;">reject</span><span style="color: #d4d4d4;">) </span><span style="color: #569cd6;">=></span><span style="color: #d4d4d4;">{ </span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">setTimeout</span><span style="color: #d4d4d4;">(()</span><span style="color: #569cd6;">=></span><span style="color: #d4d4d4;">{</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">greetings</span><span style="color: #d4d4d4;"> = </span><span style="color: #ce9178;">'Buenos Días'</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">resolve</span><span style="color: #d4d4d4;">();} , </span><span style="color: #b5cea8;">1000</span><span style="color: #d4d4d4;"> );</span></div><div><span style="color: #d4d4d4;"> });</span></div><div><span style="color: #d4d4d4;">}</span></div><br /><div><span style="color: #569cd6;">function</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">synchronize</span><span style="color: #d4d4d4;">(){</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[36m%s</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[0m'</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">'1- Empieza synchronize'</span><span style="color: #d4d4d4;">); </span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">hello</span><span style="color: #d4d4d4;">().</span><span style="color: #dcdcaa;">then</span><span style="color: #d4d4d4;">(() </span><span style="color: #569cd6;">=></span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'2-'</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">greetings</span><span style="color: #d4d4d4;">)); </span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[36m%s</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[0m'</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">'3- Acaba synchronize'</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;">}</span></div><br /><div><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[31m%s</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[0m'</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">'0- Empieza módulo'</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #dcdcaa;">synchronize</span><span style="color: #d4d4d4;">();</span></div><div><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[31m%s</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[0m'</span><span style="color: #d4d4d4;">,</span><span style="color: #ce9178;">'4- Acaba módulo'</span><span style="color: #d4d4d4;">);</span></div></div><p> siendo el resultado de la ejecución</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOJ2Bj_40HPeGa2NRnZiX_OACVNG0OJBJSl4ub0xCUvuzzHpqciqRKrUAdC9CJinS_5cY-bfGqJ8si2mqmfjcTrFGoFetugEGIHxN0fekqgt3vbspOmCCKek6x2TKsf6WOnQkE-MeYkZoN/s651/ejecucion2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="129" data-original-width="651" height="63" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOJ2Bj_40HPeGa2NRnZiX_OACVNG0OJBJSl4ub0xCUvuzzHpqciqRKrUAdC9CJinS_5cY-bfGqJ8si2mqmfjcTrFGoFetugEGIHxN0fekqgt3vbspOmCCKek6x2TKsf6WOnQkE-MeYkZoN/s320/ejecucion2.png" width="320" /></a></div><br /><h4 style="text-align: left;">Se maneja la asincronia con async/await (sincronizar4)<br /></h4><p>Este ejemplo es igual al anterior con la diferencia de que en vez de hacer uso del método then() se hace uso las palabras clave async/await. La palabra clave await se puede usar para llamar a funciones que devuelven promesas. Es el mismo comportamiento que el método then(), hasta que la promesa no se resuelve (resove()) la secuencia de ejecución no continua. Para poder usar await es obligatorio que la función en la que se usar haya sido definida como async.</p><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;"><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">greetings</span><span style="color: #d4d4d4;"> = </span><span style="color: #ce9178;">''</span><span style="color: #d4d4d4;">;</span></div><br /><div><span style="color: #569cd6;">function</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">hello</span><span style="color: #d4d4d4;">() { </span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">return</span><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">new</span><span style="color: #d4d4d4;"> </span><span style="color: #4ec9b0;">Promise</span><span style="color: #d4d4d4;">((</span><span style="color: #dcdcaa;">resolve</span><span style="color: #d4d4d4;">, </span><span style="color: #dcdcaa;">reject</span><span style="color: #d4d4d4;">) </span><span style="color: #569cd6;">=></span><span style="color: #d4d4d4;">{ </span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">setTimeout</span><span style="color: #d4d4d4;">(()</span><span style="color: #569cd6;">=></span><span style="color: #d4d4d4;">{</span><span style="color: #9cdcfe;">greetings</span><span style="color: #d4d4d4;"> = </span><span style="color: #ce9178;">'Buenos Días'</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">resolve</span><span style="color: #d4d4d4;">();} , </span><span style="color: #b5cea8;">1000</span><span style="color: #d4d4d4;"> );</span></div><div><span style="color: #d4d4d4;"> });</span></div><div><span style="color: #d4d4d4;">} </span></div><br /><div><span style="color: #569cd6;">async</span><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">function</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">synchronize</span><span style="color: #d4d4d4;">(){</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[36m%s</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[0m'</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">'1- Empieza synchronize'</span><span style="color: #d4d4d4;">); </span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">await</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">hello</span><span style="color: #d4d4d4;">(); </span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'2-'</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">greetings</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[36m%s</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[0m'</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">'3- Acaba synchronize'</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;">}</span></div><br /><div><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[31m%s</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[0m'</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">'0- Empieza módulo'</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #dcdcaa;">synchronize</span><span style="color: #d4d4d4;">();</span></div><div><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[31m%s</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[0m'</span><span style="color: #d4d4d4;">,</span><span style="color: #ce9178;">'4- Acaba módulo'</span><span style="color: #d4d4d4;">);</span></div></div><p> siendo el resultado de la ejecución</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPEQnFpbzOaT_gKLoq0zU4rUjy1lMRsyp75HXoXB5EwF-BkABiAQWyhwgeFADA1QcBPlx_99_yddEbYa-indwLvJcq7L0Ic4R9PWg_-oxi_nZa3UfzArUCk07LQt7qgOLUTmxRWJ0McOFM/s549/ejecucion4.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="127" data-original-width="549" height="74" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPEQnFpbzOaT_gKLoq0zU4rUjy1lMRsyp75HXoXB5EwF-BkABiAQWyhwgeFADA1QcBPlx_99_yddEbYa-indwLvJcq7L0Ic4R9PWg_-oxi_nZa3UfzArUCk07LQt7qgOLUTmxRWJ0McOFM/s320/ejecucion4.png" width="320" /></a></div><p> </p><h4 style="text-align: left;">Sincronizando todo el código (sincronizar5)</h4><p>En los ejemplos anteriores el console.log ('2- ', greetings) se ejecuta tras el resto de console.log, esto se debe a que lo único que sincroniza el código de los ejemplos anteriores es que se asigne el valor a la variable antes de que esta se muestre en consola. En este ejemplo se sincroniza todo, de manera que los console.log después del de la variable se ejecutan en el orden en que están numerados. Para conseguir esto hacen falta 2 promesas.</p><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;"><div><span style="color: #569cd6;">let</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">greetings</span><span style="color: #d4d4d4;"> = </span><span style="color: #ce9178;">''</span><span style="color: #d4d4d4;">;</span></div><br /><div><span style="color: #569cd6;">function</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">hello</span><span style="color: #d4d4d4;">() { </span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">return</span><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">new</span><span style="color: #d4d4d4;"> </span><span style="color: #4ec9b0;">Promise</span><span style="color: #d4d4d4;">((</span><span style="color: #dcdcaa;">resolve</span><span style="color: #d4d4d4;">, </span><span style="color: #dcdcaa;">reject</span><span style="color: #d4d4d4;">) </span><span style="color: #569cd6;">=></span><span style="color: #d4d4d4;">{ </span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">setTimeout</span><span style="color: #d4d4d4;">(()</span><span style="color: #569cd6;">=></span><span style="color: #d4d4d4;">{</span><span style="color: #9cdcfe;">greetings</span><span style="color: #d4d4d4;"> = </span><span style="color: #ce9178;">'Buenos Días'</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">resolve</span><span style="color: #d4d4d4;">();} , </span><span style="color: #b5cea8;">1000</span><span style="color: #d4d4d4;"> );</span></div><div><span style="color: #d4d4d4;"> });</span></div><div><span style="color: #d4d4d4;">} </span></div><br /><div><span style="color: #569cd6;">async</span><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">function</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">synchronize</span><span style="color: #d4d4d4;">(){</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">return</span><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">new</span><span style="color: #d4d4d4;"> </span><span style="color: #4ec9b0;">Promise</span><span style="color: #d4d4d4;"> (</span><span style="color: #569cd6;">async</span><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">function</span><span style="color: #d4d4d4;">(</span><span style="color: #dcdcaa;">resolve</span><span style="color: #d4d4d4;">, </span><span style="color: #dcdcaa;">reject</span><span style="color: #d4d4d4;">) {</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[36m%s</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[0m'</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">'1- Empieza synchronize'</span><span style="color: #d4d4d4;">); </span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">await</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">hello</span><span style="color: #d4d4d4;">();</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'2-'</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">greetings</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[36m%s</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[0m'</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">'3- Acaba synchronize'</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">resolve</span><span style="color: #d4d4d4;">();</span></div><div><span style="color: #d4d4d4;"> })</span></div><div><span style="color: #d4d4d4;">}</span></div><br /><div><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[31m%s</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[0m'</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">'0- Empieza módulo'</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #dcdcaa;">synchronize</span><span style="color: #d4d4d4;">().</span><span style="color: #dcdcaa;">then</span><span style="color: #d4d4d4;">(() </span><span style="color: #569cd6;">=></span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">console</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">log</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">'</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[31m%s</span><span style="color: #d7ba7d;">\x1b</span><span style="color: #ce9178;">[0m'</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">'4- Acaba modulo'</span><span style="color: #d4d4d4;">))</span></div></div><p> siendo el resultado de la ejecución</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAvYeyxGvcEQJXAqhRYHKZu_nqj-16Y3ilds8YQfXqSd309Kc1uD8f8kAdlQeYREhzUUMFAXx5YaT3Vv811Cll8Lnt2w6j3FKp_imPwhOd7DYZW0aXE9Zu4PiRNpO5N6ilcL-OIbAlv3n5/s639/ejecucion5.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="132" data-original-width="639" height="66" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAvYeyxGvcEQJXAqhRYHKZu_nqj-16Y3ilds8YQfXqSd309Kc1uD8f8kAdlQeYREhzUUMFAXx5YaT3Vv811Cll8Lnt2w6j3FKp_imPwhOd7DYZW0aXE9Zu4PiRNpO5N6ilcL-OIbAlv3n5/s320/ejecucion5.png" width="320" /></a></div><p></p><h4 style="text-align: left;">Terminando <br /></h4><p>Tratar con la asincronía es delicado. Dejo aquí un enlace sobre como funcionan los motores que ejecutan JavaScript. <a href="http://latentflip.com/loupe/?code=dmFyIG15RnJpZW5kQ2F0cyA9IDI7CgpmdW5jdGlvbiBzaG93TXlDYXRzKCkgewogIGNvbnNvbGUubG9nKCdteUNhdHMnLCBteUNhdHMpOwogIHNob3dNeUZyaWVuZENhdHMoKTsKfQoKZnVuY3Rpb24gc2hvd015RnJpZW5kQ2F0cygpIHsKICBjb25zb2xlLmxvZygnbXlGcmllbmRDYXRzJywgbXlGcmllbmRDYXRzKTsKICBzaG93TXlVbmNsZUNhdHMoKTsKfQoKZnVuY3Rpb24gc2hvd015VW5jbGVDYXRzKCkgewogIGNvbnNvbGUubG9nKCdNeSB1bmNsZSBkb2VzIG5vdCBoYXZlIGNhdHMuJyk7Cn0KCnNob3dNeUNhdHMoKTsKCnZhciBteUNhdHMgPSAzOw%3D%3D!!!PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D" target="_blank">latentflip.com/loupe</a></p><p>Espero que todo esto sea de ayuda y si tenéis alguna pregunta marisaafuera@gmail.com y también el código en <a href="https://github.com/MarisaAfuera/morePromisesAsyncAwait">https://github.com/MarisaAfuera/morePromisesAsyncAwait</a> </p><p><br /></p><p><br /></p><div><br /></div>Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-86933364095223966782021-09-24T04:24:00.002-07:002021-09-24T04:26:58.514-07:00Qué quiere decir Charset=”UTF-8” Casi todas las páginas html que circulan por la red incluyen un atributo que dice:
<p align="center"> <b>Charset=”UTF-8”</b> </p>
esto sirve para indicar al browser como tiene que traducir la cadena de ceros y unos que recibe y convertirlos en caracteres legibles: letras, números o símbolos especiales.</br>
Para entender lo que es UTF-8 (UTF es Unicode Transformation Format) hay hablar primero de Unicode. Unicode es un estándar ampliamente aceptado, mediante el cual a cada carácter se le asigna un número lo identifica. Por ejemplo, el carácter A mayúscula se identifica con el número hexadecimal 41 o lo que es lo mismo con el número decimal 65. Con Unicode tenemos identificados los caracteres de forma unívoca, es decir si en un ordenador está almacenado un 65 (de determinada manera) este representa a una A mayúscula.</br>
Los números en el ordenador de almacenan en base binaria, ya que solo manejan ceros y unos. Entonces lo primero que tenemos que hacer con el 65 que representa al carácter A mayúscula es convertirlo en un número binario. Para convertir de decimal a binario existe un algoritmo que consiste en ir dividiendo el número por 2 hasta que el cociente de la división es 1. Para explicarlo con un ejemplo breve veamos cómo se traduce un número 4 decimal a binario.</br>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhneEgFS7IZjM3QwPp5liV67UmXXAzIADNea50156qXrJVbsjn5Q3KuF4b-mJnKs1n5C264eODYAWjBte94wpEftOiwhtAennvwmG6S0M1T6ZxsVlzqHB6R3P-MsHdaGutm3d_wx8u4b9xP/s506/AlgoritmoBinario.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="430" data-original-width="506" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhneEgFS7IZjM3QwPp5liV67UmXXAzIADNea50156qXrJVbsjn5Q3KuF4b-mJnKs1n5C264eODYAWjBte94wpEftOiwhtAennvwmG6S0M1T6ZxsVlzqHB6R3P-MsHdaGutm3d_wx8u4b9xP/s320/AlgoritmoBinario.png"/></a></div></br>
Una vez hechas las divisiones se toman el cociente de la última y todos los restos de las anteriores en orden inverso a como se han obtenido. En este caso el resultado es que un 4 decimal se convierte en un 100 binario. De la misma manera 65 se convierte en 1000001.</br>
Una vez que sabemos cómo obtener el binario de un número llega el algoritmo UTF-8 para determinar cómo almacenar este binario en los bytes de la memoria del ordenador. Un byte es la unidad de memoria que el ordenador maneja y se compone de 8 bits, también se le llama octeto. UTF-8 almacena cada carácter en 1, 2, 3 o 4 bytes. Hay que tener en cuenta que Unicode asigna identificadores para todos los caracteres existentes en cualquier idioma y esto conlleva a que con sólo 8 bits no sea suficiente para representar todos estos caracteres.</br>
Por ejemplo, si se trata de codificar una A que en binario se representa por 7 ceros y unos, esta se almacena en un byte añadiendo un cero para completar el byte, o sea 01000001. Pero hay caracteres como ① que se traducen en más de 7 ceros y unos. Este carácter tiene asignado el decimal 9312 que se convierte en el binario 10010001100000. Este número binario no se puede almacenar en 7 bits, ya que cada bit contiene o un cero o un uno y necesita entonces 14 bits. Por lo tanto como la unidad de información que maneja el ordenador es el byte, este carácter necesita al menos 2 bytes para ser almacenada. No obstante según el algoritmo de codificación UTF-8, este carácter se almacena en 3 bytes. El motivo es que UTF-8 sigue la siguiente convención:</br></br>
<table style="border:1px solid black; border-collapse:collapse;">
<tr>
<th style="border:1px solid black; padding:4px;">Ceros y unos del binario</th>
<th style="border:1px solid black; padding:4px;">Código binario del número</th>
<th style="border:1px solid black; padding:4px;">Codificación UTF-8</th>
</tr>
<tr>
<td style="border:1px solid black; padding:4px;">Hasta 7</td>
<td style="border:1px solid black; padding:4px;">xxxxxxx</td>
<td style="border:1px solid black; padding:4px;">0xxxxxxx</td>
</tr>
<tr>
<td style="border:1px solid black; padding:4px;">Hasta 10</td>
<td style="border:1px solid black; padding:4px;">yyyyyxxxxxx</td>
<td style="border:1px solid black; padding:4px;">110yyyyy 10xxxxxx</td>
</tr>
<tr style="padding:10px;">
<td style="border:1px solid black; padding:4px;">Hasta 14</td>
<td style="border:1px solid black; padding:4px;">zzzzyyyyyyxxxxxx</td>
<td style="border:1px solid black; padding:4px;">1110zzzz 10yyyyyy 10xxxxxx</td>
</tr>
<tr>
<td style="border:1px solid black; padding:4px;">Hasta 19</td>
<td style="border:1px solid black; padding:4px;">uuuwwzzzzyyyyyyxxxxxx</td>
<td style="border:1px solid black; padding:4px;">11110uuu 10wwzzzz 10yyyyyy 10xxxxxx</td>
</tr>
</table>
</br>
Llegar a comprender a fondo estos asuntos, es la base para entender otras cosas que se construyen sobre ellos.
Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-21149155721266995532021-09-12T12:49:00.001-07:002021-09-12T12:49:19.014-07:00Javascript: Ejemplos de grupos y rangos<p>Buscar cadenas mediante grupos y rangos.</p><br/>
<table style="border: grey 2px solid; border-collapse: collapse;">
<tr>
<th style="border: grey 0.2px solid; text-align: center; width:15%">Caracter</th>
<th style="border: grey 0.2px solid; text-align: center; width:85%">Significado</th>
</tr>
<tr>
<td style="border: grey 0.2px solid; text-align: center; font-family: Courier-new; font-size: 16px; font-weight: bold">x|y</td>
<td style="border: grey 0.2px solid; text-align: left">Busca coincidencia de 'x' o 'y'</td>
</tr>
<tr>
<td style="border: grey 0.2px solid; text-align: center; font-family: Courier-new; font-size: 16px; font-weight: bold">[xyz]</td>
<td style="border: grey 0.2px solid; text-align: left">Busca coincidencia 'x, 'y' o 'z'</td>
</tr>
<tr>
<td style="border: grey 0.2px solid; text-align: center; font-family: Courier-new; font-size: 16px; font-weight: bold">[x-z]</td>
<td style="border: grey 0.2px solid; text-align: left">Busca coincidencia del rango desde 'x' hasta 'z' </td>
</tr>
<tr>
<td style="border: grey 0.2px solid; text-align: center; font-family: Courier-new; font-size: 16px; font-weight: bold">[^xyz]</td>
<td style="border: grey 0.2px solid; text-align: left">Encuentra coincidencia si no hay ningún caracter del patrón, en este caso: ni 'x', ni 'y' ni 'z'</td>
</tr>
<tr>
<td style="border: grey 0.2px solid; text-align: center; font-family: Courier-new; font-size: 16px; font-weight: bold">[^a-c]</td>
<td style="border: grey 0.2px solid; text-align: left">Encuentra coincidencia si no hay ningún caracter del rango. En este caso: ni 'a, no 'b', ni 'c'</td>
</tr>
<tr>
<td style="border: grey 0.2px solid; text-align: center; font-family: Courier-new; font-size: 16px; font-weight: bold">(x)</td>
<td style="border: grey 0.2px solid; text-align: left">Busca coincidencia del grupo. En este caso 'x'</td>
</tr>
<tr>
<td style="border: grey 0.2px solid; text-align: center; font-family: Courier-new; font-size: 16px; font-weight: bold">/n</td>
<td style="border: grey 0.2px solid; text-align: left">Siendo n un número positivo es una referencia posicional al grupo</td>
</tr>
<tr>
<td style="border: grey 0.2px solid; text-align: center; font-family: Courier-new; font-size: 16px; font-weight: bold">(?<name>xyz)</td>
<td style="border: grey 0.2px solid; text-align: left">Busca xyz y establece el nombre name para ese grupo. Luego se puede volver a utilizar</td>
</tr>
<tr>
<td style="border: grey 0.2px solid; text-align: center; font-family: Courier-new; font-size: 16px; font-weight: bold">(?:x)</td>
<td style="border: grey 0.2px solid; text-align: left">Busca x el grupo no se puede volver a utilizar</td>
</tr>
</table>
<br>
<h1> Ejemplos </h1>
<br>
<p><script src="https://gist.github.com/MarisaAfuera/8d1773f0b1638963a0e117131686fd42.js"></script></p>
<br>
<p>Espero que esto ayude</p>
Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-18473518436437771392021-08-30T07:50:00.003-07:002021-08-30T07:54:12.360-07:00Javascript: Ejemplo de Promise y Async/Await, manejando la asincronía<p>Ejemplo de uso del objeto Promise y de las palabras Async/await para manejar la asincronía no bloqueante que es característica de javascript.</p>
<p>El ejemplo contiene tres piezas de código:</p></br>
1) sincronizar1.js</br>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0A6HC2IeqCqefEilDWlPtFUqrqa7oDbBMDfzxsDGyQLpYv67P-0mFrztGym-wlFYoLkBDq7TeTrhgvV6xs1md-sG207VeL8y-izA9g6kaWqA8_uWOhkSjU04RQpHPJ8GNYpOEHnbOzn89/s541/codigoSincronizar1.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="286" data-original-width="541" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0A6HC2IeqCqefEilDWlPtFUqrqa7oDbBMDfzxsDGyQLpYv67P-0mFrztGym-wlFYoLkBDq7TeTrhgvV6xs1md-sG207VeL8y-izA9g6kaWqA8_uWOhkSjU04RQpHPJ8GNYpOEHnbOzn89/s320/codigoSincronizar1.png"/></a></div></br>
En este código se muestra como la función setTimeout desencadena una función asíncrona no bloqueante que asigna valor a una variable global. El resultado de ejecutar
sincronizar1.js es:</br>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQBrgn2AMUliLHeQoIjv_UXVtQWNNo8Kmxm2_As2-7V4t7vdxErCkyo1m7WDp3tjnU3-VgdMwouxA_RPt-ymoXD51zXxcvRGwKZApTt9JpLMo8tpziTxRu0p8KuVv6dSXe2BW2GA7mk5GA/s368/ejecuci%25C3%25B3nSincronizar1.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="74" data-original-width="368" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQBrgn2AMUliLHeQoIjv_UXVtQWNNo8Kmxm2_As2-7V4t7vdxErCkyo1m7WDp3tjnU3-VgdMwouxA_RPt-ymoXD51zXxcvRGwKZApTt9JpLMo8tpziTxRu0p8KuVv6dSXe2BW2GA7mk5GA/s320/ejecuci%25C3%25B3nSincronizar1.png"/></a></div></br>
El resultado es que cuando se muestra la variable todavía no ha pasado un segundo y contiene el valor inicial, es decir nada.</br></br>
2) sincronizar2.js</br>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLHvve7h2HSiILT1FjmpMD1Su3i1gv_I7ZltjXH9NA9nc6wlk_wwhT_tmsdP1OhU973a7Myh_e9yebrw_VvSo8tdZNPqv9_wsgiZ90oqvfhgKTI41DNa8oZKIM38bE80ERYFxr6Ox8HKxs/s578/codigoSincronizar2.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="345" data-original-width="578" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLHvve7h2HSiILT1FjmpMD1Su3i1gv_I7ZltjXH9NA9nc6wlk_wwhT_tmsdP1OhU973a7Myh_e9yebrw_VvSo8tdZNPqv9_wsgiZ90oqvfhgKTI41DNa8oZKIM38bE80ERYFxr6Ox8HKxs/s320/codigoSincronizar2.png"/></a></div></br>
En este código se muestra el mismo ejemplo y cómo con un objeto de tipo Promesa se accede al valor de la variable global cuando esta está cargada.</br>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXBX8XWh7rHC6x-_WkMSwMPbP8jyij8jKoiMhelj6SYlF5qO27pUmGdNYRAaajIG1aIyxdJf_ZdFxyADKCFyFDPYk_p-6FbCjf__u2aTVZZaKVbC3BUiUKgqT2J0qNxPc_8bImdS-ElKA7/s371/ejecuci%25C3%25B3nSincronizar2.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="74" data-original-width="371" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXBX8XWh7rHC6x-_WkMSwMPbP8jyij8jKoiMhelj6SYlF5qO27pUmGdNYRAaajIG1aIyxdJf_ZdFxyADKCFyFDPYk_p-6FbCjf__u2aTVZZaKVbC3BUiUKgqT2J0qNxPc_8bImdS-ElKA7/s320/ejecuci%25C3%25B3nSincronizar2.png"/></a></div></br>
El resultado es que cuando se ejecuta el método .then del objeto Promise, la variable ya está cargada con el valor 'Buenos dias'. Pero el console log del método
.then se ejecuta al final.</br></br>
3) sincronizar3.</br>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpfuTOy5NHAhmel1zscuzcGE-rVQ5FPdN0ORjBID3NLDqRM8VWxzGz9HJx4xGPOMeA1KP246tzDv4LngcqfZJ9s5VNTgsELoPb1nyLO0rBO8rp3eKP4K9Y1zQ7MJFl2WePmeQdylh8sLwU/s502/codigoSincronizar3.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="353" data-original-width="502" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpfuTOy5NHAhmel1zscuzcGE-rVQ5FPdN0ORjBID3NLDqRM8VWxzGz9HJx4xGPOMeA1KP246tzDv4LngcqfZJ9s5VNTgsELoPb1nyLO0rBO8rp3eKP4K9Y1zQ7MJFl2WePmeQdylh8sLwU/s320/codigoSincronizar3.png"/></a></div></br>
En este código se muestra el mismo ejemplo combinando la Promesa con el uso de las palabras clave Async/await, consiguiendo ejecutar las sentencias
en el orden deseado.</br>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8rLnSkN83uUuaZWBXP50Rs0-ZgoCxeuu_yctvA1FvSh1s-6oPRznpZAld55Fp3ipzuAPR0-iCuIb7MBeoP8DrVWYpkJnhTxl9lGte8nmGlS7ntZZacW-Gaf0BafeKQ1_TbYCPILvWuh79/s362/ejecuci%25C3%25B3nSincronizar3.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="77" data-original-width="362" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8rLnSkN83uUuaZWBXP50Rs0-ZgoCxeuu_yctvA1FvSh1s-6oPRznpZAld55Fp3ipzuAPR0-iCuIb7MBeoP8DrVWYpkJnhTxl9lGte8nmGlS7ntZZacW-Gaf0BafeKQ1_TbYCPILvWuh79/s320/ejecuci%25C3%25B3nSincronizar3.png"/></a></div></br>
El resultado es que además de que la variable contiene 'Buenos días' las sentencias console se muestran en orden 1, 2 y luego 3.</br></br>
<h3>Referencias</h3>
Puedes obtener la explicación en <a href="https://youtu.be/zbfKBbQlFzw" target="_blank">mi video en youtube</a></br>
Puedes obtener el código javascript en <a href="https://github.com/MarisaAfuera/promisesawaitasync.git" target="_blank">Mi repositorio de Github</a>
Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-80563767756487552882021-08-23T09:00:00.004-07:002021-08-23T09:08:39.563-07:00Herramientas para desarrolladores de Chrome<p>El desarrollo de software en cualquier lenguaje de programación o entorno de
trabajo entraña dificultades.</p><p>Para escribir código se utilizan IDEs (integrated
development environment) que suministran al programador herramientas para
facilitar su trabajo. Entre estas herramientas están las de depuración (debug).
Los debuggers son muy útiles para los desarrolladores puesto que incorporan
funcionalidad para ayudarle a buscar errores y problemas que de otra forma
tendrían que buscar de forma manual e intuitiva.</p><p>En el caso de desarrollos para aplicaciones web, las herramientas de depuranción de los IDEs sirven para depurar el código que genera html, css y javascript que se envía al browser.Una vez que ese código es generado y enviado la única forma de depurarlo es en el browser que es el que lo está inerpretando. </p><p>Google Chrome incorpora herramientas de depuración. Los demás browsers también tienen
este ripo de herramientas pero las mas completas son las de Chrome. Con Chrome sobre
una página html cargada en el browser se pueden analizar numerosos aspectos que
ayudan a localizar malos funcionamientos y errores. Las herramientas de
desarrollador de Chrome, permiten: </p><ul style="text-align: left;"><li>Localizar un elemento del DOM (Document Object Model) tanto desde la vista del usuario como desde el código fuente.</li><li>Saber que estilos se están aplicando a cada elemento. Si se están aplicando de forma directa (inline), por hoja de estilo, porque se han heredado de algún elemento padre o porque son el valor de defecto.</li><li>Consultar los mensajes que el browser genera o los que genera el programador utilizando el objeto "console" de javascript.</li><li>Se puede consultar el número de línea en el que se ha producido un error para subsanarlo.</li><li>Se pueden poner puntos de ruptura (breakpoints) para detener el programa donde convenga al programador y luego avanzar instrucción a instrucción para ver como progresa el flujo de control del programa.<br /></li><li>Se puede consultar el contenido de las variables e incluso modificar su valor para observar el comportamiento del programa con los nuevos valores almacenados.</li><li>Se puede saber el tiempo que tarda en cargarse cada elemento de la página.</li><li>etc.</li></ul><p>Si quieres ver una pequeña intro al funcionamiento de estas herramientas, puedes reproducir los videos Herramientas de desarrollador de Chrome (1ª parte) <a href="https://youtu.be/ZgZ7jpqLgag" target="_blank">aquí</a> y Herramientas de desarrollador de Chrome (2ª parte) <a href="https://youtu.be/k50HfxXTQQo" target="_blank">aquí</a></p><p>Espero que esta información te sea de utilidad y te ayude a escribir código siendo más feliz. Y serás más feliz porque si lo utilizas entenderás mejor lo que está sucediendo trás tú programación.<br /></p><p> <br /></p>Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-31833200828940041922021-08-10T11:16:00.051-07:002021-08-10T11:35:15.331-07:00Enseñando scratch a los niños<p>Crear programas para ordenadores o teléfonos desarrolla las habilidades para la resolución de problemas lógicos. Si se enseña a programar a un niño se potencian estás habilidades a una edad temprana que es cuando mejor se aprende y este aprendizaje es muy útil para mejorar sus procesos cognitivos.</p>
<p>El Instituto Tecnológico de Massachussets (MIT) ha desarrollado un lenguaje de programación visual que permite a los pequeños de 8 a 16 años aprender los conceptos de programación de ordenadores. Existe una versión junior, ScratchJr que está diseñado para niños de 5 a 7 años.</p>
<p>Con Scratch se pueden hacer programas muy sencillos, pero a la vez incorpora estructuras que tienen los lenguajes de programación profesionales. Se programa con bloques que están agrupados por las acciones que realizan y están identificados por colores. Se puede mover los objetos por la pantalla, agrandarlos y empequeñecerlos, hacer que desaparezcan y aparezcan, que emitan sonidos, que muestren bocadillos, tomar decisiones condicionales, ejecutar bucles, crear variables, etc. Se aprende rápido lo más básico y también hay campo para profundizar.</p>
<p>La plataforma está además preparada para que los pequeños programadores puedan compartir sus creaciones con otros. Además hay múltiples sitios donde se ofrecen ideas para avanzar en el aprendizaje en forma de retos. Estos retos consisten en proyectos ya llevados a cabo que se presentan para que el programador los intente reproducir y sobre los cuales se puede consultar su código para aprender como están hechos.</p>
<p>En este artículo quiero presentaros un canal de youtube en el que he dejado unos videos para iniciar a los adultos en el uso de Scratch. El objetivo de estos videos es que una vez que entiendas como Scratch funciona, puedas transmitirselo a los pequeños que tengas alrededor.</p>
<p>Los videos están en <a href="https://youtu.be/iKgPIT5XotY" target="_blank">Introducción a Scratch</a> y hay otros dos que enseñan un proyecto más completo: <a href="https://youtu.be/7c8hfv21aaQ" target="_blank">El gato se va al castillo (Parte 1)</a> y <a href="https://youtu.be/LYoh6J6HCWQ" target="_blank">El gato se va al castillo (Parte 2)</a>. </p>
<p>Para acceder a Scratch <a href="https://scratch.mit.edu">pulsa aquí</a></p>Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-21270046864225284452021-06-06T02:26:00.056-07:002021-06-06T03:23:19.634-07:00JavaScript: Ejemplos de aserciones en expresiones regulares<p>Incluyen límites para cadenas, palabras y caracteres. También búsquedas de cadenas que están precedidas o seguidas por otras subcadenas.</p><br/>
<table style="border: grey 2px solid; border-collapse: collapse;">
<tr>
<th style="border: grey 0.2px solid; text-align: center; width:15%">Caracter</th>
<th style="border: grey 0.2px solid; text-align: center; width:85%">Significado</th>
</tr>
<tr>
<td style="border: grey 0.2px solid; text-align: center; font-family: Courier-new; font-size: 16px; font-weight: bold">^</td>
<td style="border: grey 0.2px solid; text-align: left">Busca coincidencia al comienzo cadena</td>
</tr>
<tr>
<td style="border: grey 0.2px solid; text-align: center; font-family: Courier-new; font-size: 16px; font-weight: bold">$</td>
<td style="border: grey 0.2px solid; text-align: left">Busca coincidencia al final cadena</td>
</tr>
<tr>
<td style="border: grey 0.2px solid; text-align: center; font-family: Courier-new; font-size: 16px; font-weight: bold">\b</td>
<td style="border: grey 0.2px solid; text-align: left">Busca límites de palabra. Una palabra empieza y termina donde un caracter de palabra no es precedido o seguido por otro caracter de palabra. Se consideran caracteres de palabra las letras mayúsculas y minúsculas del alfabeto latino, los números y el caracter de subrayado. </td>
</tr>
<tr>
<td style="border: grey 0.2px solid; text-align: center; font-family: Courier-new; font-size: 16px; font-weight: bold">\B</td>
<td style="border: grey 0.2px solid; text-align: left">Busca límites de no palabra. Es decir el caracter anterior o siguiente a un caracter son del mismo tipo del propio caracter </td>
</tr>
<tr>
<td style="border: grey 0.2px solid; text-align: center; font-family: Courier-new; font-size: 16px; font-weight: bold">x(?=y)</td>
<td style="border: grey 0.2px solid; text-align: left">Búsqueda hacía delante. Coincide x solo si x está seguida de y</td>
</tr>
<tr>
<td style="border: grey 0.2px solid; text-align: center; font-family: Courier-new; font-size: 16px; font-weight: bold">x(?!y)</td>
<td style="border: grey 0.2px solid; text-align: left">Búsqueda hacía delante negativa. Coincide x solo si x no está seguida de y</td>
</tr>
<tr>
<td style="border: grey 0.2px solid; text-align: center; font-family: Courier-new; font-size: 16px; font-weight: bold">(?<=y)x</td>
<td style="border: grey 0.2px solid; text-align: left">Búsqueda hacía detrás. Coincide x solo si x está precedida de y</td>
</tr>
<tr>
<td style="border: grey 0.2px solid; text-align: center; font-family: Courier-new; font-size: 16px; font-weight: bold">(?<!y)x</td>
<td style="border: grey 0.2px solid; text-align: left">Búsqueda hacía detrás negativa. Coincide x solo si x no está precedida de y</td>
</tr>
</table>
<br>
<h1> Ejemplos </h1>
<br>
<p><script src="https://gist.github.com/MarisaAfuera/0a819545455cda4688f910f78b605fd4.js"></script></p>
<br>
<p>Espero que esto ayude</p>
Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0tag:blogger.com,1999:blog-895730532451445280.post-85195590378594711152021-05-12T14:26:00.009-07:002021-09-12T12:55:11.033-07:00Javascript: Expresiones regulares<p>Una expresión regular es un patrón usado para buscar coincidencias de combinaciones de caracteres dentro de otras cadenas de caracteres (strings). En JavaScript, estos patrones son objetos. </p><p>Estos patrones se pueden usar como métodos del objeto tipo RegExp con los métodos exec() y test() y también con objetos String con los métodos match(), matchAll(), replace(), replaceAll(), search() y split(). </p><h3 style="text-align: left;">Creación de expresiones regulares <br /></h3><p>Para crear expresiones regulares existen 2 maneras: </p><ul style="text-align: left;"><li>Usando un literal que consiste en un patrón encerrado entre //. </li><script src="https://gist.github.com/MarisaAfuera/2e400a01168d82d0617936e545b67c98.js"></script></ul><p>de esta forma la compilación del patrón se realiza cuando el script se carga. En los casos en los que la expresión regular permanece constante, esta manera mejora el rendimiento.</p><ul style="text-align: left;"><li>Usando el constructor de RegExp</li><script src="https://gist.github.com/MarisaAfuera/122159de36b1190450dce7c84ab114f6.js"></script></ul><p>usando la función constructor la compilación se hace en tiempo de ejecución. Se debe usar esta forma cuando la expresión regular cambia durante la ejecución o no se conoce el patrón de antemano y se obtiene durante la ejecución del script.</p><h3 style="text-align: left;">Utilizando patrones <br /></h3><p>Una expresión regular está compuesta simplemente de caracteres tal como /abc/ o una combinación de caracteres simples y otros especiales tal como /ab*c/. </p><p>En el caso de /abc/ este patrón busca la coincidencia con la cadena abc dentro de la cadena analizada. Por ejemplo: </p><script src="https://gist.github.com/MarisaAfuera/35b0c7c620a564a240c6886753dfb090.js"></script><script src="https://gist.github.com/MarisaAfuera/35a246a20b191ae2ee5942bd962a4bd5.js"></script><p> En el caso de /ab*c/, el caracter * es un caracter especial que indica en el patrón que el caracter b en este caso se puede presentar 1 o varias veces. Por ejemplo: </p><script src="https://gist.github.com/MarisaAfuera/ad88a1348b8ed4b733473417fa8eac92.js"></script><script src="https://gist.github.com/MarisaAfuera/0e469601666a6ccbf51c18d8e7411f2c.js"></script><p> </p><h3 style="text-align: left;">Qué patrones se pueden construir</h3><p>Entonces un patrón está compuesto por una cadena de caracteres entre barras oblicuas (slashes). Los caracteres pueden representarse a ellos mismos (caracteres simples) o pueden tener un significado especial (carateres especiales). Según la clasificación que hacen en <a href="https://developer.mozilla.org/es/" target="_blank">MDN Web Docs</a> de los tipos de caracteres especiales son:</p><ul style="text-align: left;"><li>Aserciones.- indican el comienzo y el final de líneas y palabras, y otros patrones. <a href="http://www.asuntosoftware.com/2021/06/" target="_blank">Ejemplos de aserciones</a><br /></li><li>Clases de caracteres.- Distingue diferentes tipos de caracteres. Por ejemplo, distinguir entre letras y dígitos.</li><li>Grupos y rangos.- indican grupos y rangos de caracteres. <a href="http://www.asuntosoftware.com/2021/09/javascript-ejemplos-de-grupos-y-rangos.html" target="_blank">Ejemplos de grupos y rangos</a></li><li>Cuantificadores.- indica el número de repeticiones.</li><li>Caracteres de escape de propiedades Unicode.- indica por ejemplo, letras mayúsculas y minúsculas, símbolos matemáticos y de puntuación. <br /></li></ul><h3 style="text-align: left;">Conclusiones</h3><p>Merece la pena que todo programador le dedique algunas hora a aprender como se manejan las expresiones regulares. Esto ayuda a que en el momento de tener que usarlas se manejen con soltura y no sean una piedra en el camino para poder entender o construir el código. Y no se aprenden en 5 minutos.<br /></p><p> </p>Marisa Afuerahttp://www.blogger.com/profile/16351030326350550810noreply@blogger.com0