Páginas

domingo, 26 de diciembre de 2021

La paradoja del circunnavegante

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á.

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.

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.

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á: 4 minutos * (40.075 km / 111,32 km) 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.

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.

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.

miércoles, 1 de diciembre de 2021

Javascript: Ejemplos de Template Literal

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. 

Ejemplo simple

Un ejemplo muy simple de es:

let miPrimerTemplateLiteral = `Este es un template literal`;

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 ".

Ejemplo de intercalado de expresiones

Un ejemplo que si saca partido a las posibilidades de un Template Literal sería:

let nombre = "Luis";
let cantidad = 23;
let precioUnitario= 105;
let iva = 1.21;
let plantilla= `Querido/a ${nombre},\nEspero que te encuentres bien.
Te recuerdo que el importe de la factura asciende a ${cantidad*precioUnitario*iva}`;
console.log(plantilla);
// Resultado:
// Querido/a Luis,
// Espero que te encuentres bien.
// Te recuerdo que el importe de la factura asciende a 2922.15

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.

Ejemplo de anidación

Los template literal se pueden poner unos dentro de otros

let color = 'rojas';
let count = 3;
let message = `Tengo ${color ? `${count} manzanas ${color}` : `${count} manzanas`} `; // Noncompliant; nested template strings not easy to read
console.log('Mesagge ', message)
// Resultado: Mesagge  Tengo 3 manzanas rojas

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

let apples = color ? `${count} manzanas ${color}` : `${count} manzanas`;
message = `Tengo ${apples}`;
console.log('Mesagge ', message)
// Resultado: Mesagge  Tengo 3 manzanas rojas
 

Ejemplo de templates etiquetados

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.

function templatetag(literales, ...expresiones){
  console.log('lit ', literales, 'exp ', expresiones)
}

templatetag`amigo ${2+2} mio`
// Resultado; lit  [ 'amigo ', ' mio' ] exp  [ 4 ]

Esta característica de los Template Literal permite procesar su contenido según se requiera, por ejemplo

function priceonSeason(literales, ...expresiones) {
  let precio = 100;
  if (literales[1] == ' diciembre')    
     return `Su reserva para temporada baja ha sido confirmada.
     ${expresiones[0]} personas por un importe de ${precio*0.90}`
  else
    return `Su reserva para temporada alta ha sido confirmada.
    ${expresiones[0]} personas por un importe de ${precio}`
}
let pax = 2;
let respond = priceonSeason`Reserva de plaza para ${pax} diciembre`;
console.log ('Ejemplo etiquetado', respond)
// Resultado
// Ejemplo etiquetado Su reserva para temporada baja ha sido confirmada.      
//      2 personas por un importe de 90
 

Conclusión

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.

domingo, 7 de noviembre de 2021

Javascript: Ejemplos de uso del operador spread

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. 

Con spread se puede: 

  • En llamadas a funciones, que arrays o strings expandan sus elementos. 
  • Operar entre arrays, el operador expande sus elementos. Se pueden copiar, mezclar, intercalar.
  • Operar con objetos spread expande los pares clave-valor. Lo mismo que los arrays 

Ejemplos básicos


// expande el string en sus 3 caracteres
console.log('String expandido: ', ..."abc"); 
// expande el array en sus 4 elementos
console.log('Array expandido: ', ...[1,2,3,4]); 
// Expande el primer objeto y le añade el par clave-valor masattr: 'def'
console.log('Objeto expandido: ', {...{id1desc:'abc'}, masattr'def' }); 
// Expande los arrays y crea uno nuevo con los elementos de los dos
console.log('Une dos arrays: ',[...[1,2,3,4],...[5,6]])

// String expandido:  a b c
// Array expandido:  1 2 3 4
// Objeto expandido:  { id: 1, desc: 'abc', masattr: 'def' }
// Une dos arrays:  [ 1, 2, 3, 4, 5, 6 ]

 

Otros ejemplos

 En el siguiente ejemplo se intercalas los elementos de un array en otro

// Spread en array 
let otrosIdiomas = ['inglés''aleman'];
let idiomasHablados = ['español', ...otrosIdiomas'frances'];
console.log ('Ver idiomasHablados: 'idiomasHablados)
// Ver idiomasHablados:  [ 'español', 'inglés', 'aleman', 'frances' ]

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.

// Copiar array como arr.slice()
let numeros1 = [123];
let numeros2 = [...numeros1]; 
numeros2.push(4);
console.log ('numeros1 y numeros2: 'numeros1numeros2
// numeros1 y numeros2:  [ 1, 2, 3 ] [ 1, 2, 3, 4 ]

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.

//Spread en llamadas a funciones
function miFuncion(a1a2a3) { 
    console.log ('Argumentos: 'a1a2a3)
}
let argumentos = [012];
miFuncion(...argumentos);

En el siguiente ejemplo se copian y mezclan objetos siendo de nuevo una copia poco profunda.

// Con objetos
let objeto1 = { desc'ob1'p11 };
let objeto2 = { desc'ob2'p22 };
let objetoCopiado = { ...objeto1 };
let objetoMezclado = { ...objeto1, ...objeto2 };
console.log ('Objetos copiado y mezclado: 'objetoCopiadoobjetoMezclado)
// Objetos copiado y mezclado:  { desc: 'ob1', p1: 1 } { desc: 'ob2', p1: 1, p2: 2 }

 

Conclusión

El operador spread facilita las tareas del desarrollador cuando se trata de realizar ciertas operaciones con objetos iterables: array, strings y objetos.


 

lunes, 1 de noviembre de 2021

JavaScript: Ejemplo del método Promise.all()

Este método es útil cuando se han creado varias promesas y es necesario realizar una operación solo cuando se hayan resuelto todas.

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.

Ejemplo

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.

let datosA = new Promise((resolvereject=>
                   {setTimeout(()=> (resolve("datos de A"), 2000))});
let datosB = new Promise((resolvereject=> 
                   {setTimeout(()=> (resolve("datos de B"), 1000))});

Promise.all([datosAdatosB]).then((result=> 
                                {console.log ("datosAyB "result)})

// RESULTADO: datosAyB  [ 'datos de A', 'datos de B' ]

Otro ejemplo

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.

let datosA;
let datosB;

let rellenadatosA = new Promise((resolvereject=> 
                            {setTimeout(()=> 
                               {datosA="datos A"resolve(datosA)}, 2000)});
let rellenadatosB = new Promise((resolvereject=> 
                            {setTimeout(() => 
                               {datosB="datos B"resolve(datosB)}, 1000)});

Promise.all([rellenadatosA]).then(() => console.log ("datosAyB "datosAdatosB));

// datosAyB  datos A datos B

Espero que sea de ayuda. Si quedan dudas, dejadlas en comentarios. 

Chao


jueves, 28 de octubre de 2021

Javascript: Otro ejemplo sencillo de callback, promise y async/await

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. 

EJEMPLO 

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: 
 

No se maneja la asincronía (sincronizar1.js)

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.
 
let greetings = '';

function hello() {      
  setTimeout(()=>{greetings = 'Buenos Días';}, 1000);  
}

function synchronize(){
  console.log ('\x1b[36m%s\x1b[0m''1- Empieza synchronize');
  hello();
  console.log ('2- greetings está vacio'greetings);
  console.log ('\x1b[36m%s\x1b[0m''3- Acaba synchronize');
}

console.log ('\x1b[31m%s\x1b[0m''0- Empieza módulo');
synchronize();
console.log ('\x1b[31m%s\x1b[0m','4- Acaba módulo');
 
siendo el resultado de la ejecución

 

Se maneja la asincronía con callback (sincronizar2.js)

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.

let greetings = '';

function hello(fdespues) { 
   setTimeout(()=>{
     greetings = 'Buenos Días'fdespues()}, 1000 );  
}

function mostrar(){
    console.log ('2-'greetings)
}

function synchronize(){
  console.log ('\x1b[36m%s\x1b[0m''1- Empieza synchronize');
  hello(mostrar);  
  console.log ('\x1b[36m%s\x1b[0m''3- Acaba synchronize');
}

console.log ('\x1b[31m%s\x1b[0m''0- Empieza módulo');
synchronize();
console.log ('\x1b[31m%s\x1b[0m','4- Acaba módulo');

 siendo el resultado de la ejecución


 Se maneja la asincronía con Promise y then() (sincronizar3.js)

 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().

let greetings = '';

function hello() { 
  return new Promise((resolvereject=>{    
      setTimeout(()=>{
        greetings = 'Buenos Días';
        resolve();} , 1000 );
  });
}

function synchronize(){
  console.log ('\x1b[36m%s\x1b[0m''1- Empieza synchronize'); 
  hello().then(() => console.log ('2-'greetings));    
  console.log ('\x1b[36m%s\x1b[0m''3- Acaba synchronize');
}

console.log ('\x1b[31m%s\x1b[0m''0- Empieza módulo');
synchronize();
console.log ('\x1b[31m%s\x1b[0m','4- Acaba módulo');

 siendo el resultado de la ejecución


Se maneja la asincronia con async/await (sincronizar4)

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.

let greetings = '';

function hello() { 
  return new Promise((resolvereject=>{    
      setTimeout(()=>{greetings = 'Buenos Días';
                      resolve();} , 1000 );
  });

async function synchronize(){
  console.log ('\x1b[36m%s\x1b[0m''1- Empieza synchronize'); 
  await hello();    
  console.log ('2-'greetings);
  console.log ('\x1b[36m%s\x1b[0m''3- Acaba synchronize');
}

console.log ('\x1b[31m%s\x1b[0m''0- Empieza módulo');
synchronize();
console.log ('\x1b[31m%s\x1b[0m','4- Acaba módulo');

 siendo el resultado de la ejecución

 

Sincronizando todo el código (sincronizar5)

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.

let greetings = '';

function hello() { 
  return new Promise((resolvereject=>{    
      setTimeout(()=>{greetings = 'Buenos Días';
                      resolve();} , 1000 );
  });

async function synchronize(){
  return new Promise (async function(resolvereject) {
    console.log ('\x1b[36m%s\x1b[0m''1- Empieza synchronize'); 
    await hello();
    console.log ('2-'greetings);
    console.log ('\x1b[36m%s\x1b[0m''3- Acaba synchronize');
    resolve();
  })
}

console.log ('\x1b[31m%s\x1b[0m''0- Empieza módulo');
synchronize().then(() => console.log ('\x1b[31m%s\x1b[0m''4- Acaba modulo'))

 siendo el resultado de la ejecución

Terminando

Tratar con la asincronía es delicado. Dejo aquí un enlace sobre como funcionan los motores que ejecutan JavaScript. latentflip.com/loupe

Espero que todo esto sea de ayuda y si tenéis alguna pregunta marisaafuera@gmail.com y también el código en https://github.com/MarisaAfuera/morePromisesAsyncAwait




viernes, 24 de septiembre de 2021

Qué quiere decir Charset=”UTF-8”

Casi todas las páginas html que circulan por la red incluyen un atributo que dice:

Charset=”UTF-8”

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.
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.
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.

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.
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.
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:

Ceros y unos del binario Código binario del número Codificación UTF-8
Hasta 7 xxxxxxx 0xxxxxxx
Hasta 10 yyyyyxxxxxx 110yyyyy 10xxxxxx
Hasta 14 zzzzyyyyyyxxxxxx 1110zzzz 10yyyyyy 10xxxxxx
Hasta 19 uuuwwzzzzyyyyyyxxxxxx 11110uuu 10wwzzzz 10yyyyyy 10xxxxxx

Llegar a comprender a fondo estos asuntos, es la base para entender otras cosas que se construyen sobre ellos.

domingo, 12 de septiembre de 2021

Javascript: Ejemplos de grupos y rangos

Buscar cadenas mediante grupos y rangos.


Caracter Significado
x|y Busca coincidencia de 'x' o 'y'
[xyz] Busca coincidencia 'x, 'y' o 'z'
[x-z] Busca coincidencia del rango desde 'x' hasta 'z'
[^xyz] Encuentra coincidencia si no hay ningún caracter del patrón, en este caso: ni 'x', ni 'y' ni 'z'
[^a-c] Encuentra coincidencia si no hay ningún caracter del rango. En este caso: ni 'a, no 'b', ni 'c'
(x) Busca coincidencia del grupo. En este caso 'x'
/n Siendo n un número positivo es una referencia posicional al grupo
(?xyz) Busca xyz y establece el nombre name para ese grupo. Luego se puede volver a utilizar
(?:x) Busca x el grupo no se puede volver a utilizar

Ejemplos



Espero que esto ayude

lunes, 30 de agosto de 2021

Javascript: Ejemplo de Promise y Async/Await, manejando la asincronía

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.

El ejemplo contiene tres piezas de código:


1) sincronizar1.js

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:

El resultado es que cuando se muestra la variable todavía no ha pasado un segundo y contiene el valor inicial, es decir nada.

2) sincronizar2.js

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.

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.

3) sincronizar3.

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.

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.

Referencias

Puedes obtener la explicación en mi video en youtube
Puedes obtener el código javascript en Mi repositorio de Github

lunes, 23 de agosto de 2021

Herramientas para desarrolladores de Chrome

El desarrollo de software en cualquier lenguaje de programación o entorno de trabajo entraña dificultades.

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.

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. 

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: 

  • Localizar un elemento del DOM (Document Object Model) tanto desde la vista del usuario como desde el código fuente.
  • 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.
  • Consultar los mensajes que el browser genera o los que genera el programador utilizando el objeto "console" de javascript.
  • Se puede consultar el número de línea en el que se ha producido un error para subsanarlo.
  • 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.
  • Se puede consultar el contenido de las variables e incluso modificar su valor para observar el comportamiento del programa con los nuevos valores almacenados.
  • Se puede saber el tiempo que tarda en cargarse cada elemento de la página.
  • etc.

Si quieres ver una pequeña intro al funcionamiento de estas herramientas, puedes reproducir los videos Herramientas de desarrollador de Chrome (1ª parte) aquí y Herramientas de desarrollador de Chrome (2ª parte) aquí

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.

 

martes, 10 de agosto de 2021

Enseñando scratch a los niños

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.

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.

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.

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.

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.

Los videos están en Introducción a Scratch y hay otros dos que enseñan un proyecto más completo: El gato se va al castillo (Parte 1) y El gato se va al castillo (Parte 2).

Para acceder a Scratch pulsa aquí

domingo, 6 de junio de 2021

JavaScript: Ejemplos de aserciones en expresiones regulares

Incluyen límites para cadenas, palabras y caracteres. También búsquedas de cadenas que están precedidas o seguidas por otras subcadenas.


Caracter Significado
^ Busca coincidencia al comienzo cadena
$ Busca coincidencia al final cadena
\b 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.
\B Busca límites de no palabra. Es decir el caracter anterior o siguiente a un caracter son del mismo tipo del propio caracter
x(?=y) Búsqueda hacía delante. Coincide x solo si x está seguida de y
x(?!y) Búsqueda hacía delante negativa. Coincide x solo si x no está seguida de y
(?<=y)x Búsqueda hacía detrás. Coincide x solo si x está precedida de y
(?<!y)x Búsqueda hacía detrás negativa. Coincide x solo si x no está precedida de y

Ejemplos



Espero que esto ayude