5. Programación Funcional y Asíncrona en JS

En este tema profundizaremos sobre los aspectos de programación funcional y asíncrona en JS. Aprenderás a:

  1. Entender qué es la programación funcional

  2. Usar programación funcional en tu software

  3. Comenzar a usar promesas y el API Fetch

Está organizado en 8 talleres de unas 3 sesiones de clase. En total unas 24 sesiones de clase más tu trabajo en casa.

La dedicación depende del conocimiento previo, motivación y capacidad de aprendizaje del estudiante para esa sesión en concreto.

5.1. Introducción a la programación Funcional

  1. Introducción a la programación funcional (hasta minuto 15)

  2. Hay dos grandes paradigmas (formas de resolver un problema) en programación:

    1. Imperativo: dices cómo vas a resolver el problema

    2. Declarativo: declaras el problema (no tanto cómo vas a hacerlo)

  3. Con este enfoque, surgen los diferentes estilos de programación (también llamados paradigmas ).

    1. Programación Estructurada: dices, paso a paso, qué hay que hacer (instrucciones + sentencias de control + sentencias de repetición)

    2. Programación Orientada a objetos): defines objetos, que contienen características y funcionalidad propia, y que se relacionan con otros objetos

    3. Programación Funcional (declarativa): declaras funciones, con algunos criterios generales, para resolver tu problema

  4. Características de la programación funcional:

    1. Funciones como elementos de primera clase

    2. Inmutables: para la misma entrada siempre devuelve la misma salida. No se modifican los datos de entrada.

    3. Deben ser puras, sin efectos colaterales: no cambias el estado dentro de la función

    4. Funciones de orden superior: pueden recibir funciones como argumentos de entrada y devolver funciones como argumentos de salida

  5. En JS una función es un elemento de primera clase , es decir

    1. Puedes asignar una función a una variable (y utilizarla). Ojo a los paréntesis (sólo cuando se ejecuta)

    2. Puedes usar funciones como argumentos (porque son elementos de primera clase, es decir, valores)

    3. Puedo usar una función como argumento en otra función (función callback), porque es un valor

    4. Puedo devolver una función como resultado de una función, porque es un valor

  6. Al devolver una función puedo definirla dentro de la función «anfitriona» o mejor definirla antes (hasta que tengas cierta experiencia)

Actividad T05-A01. Introducción a la programación funcional

  1. Define la función suma(n,m), que me devuelva la suma de esos dos números.

  2. Defínela como función anónima y la asignas a la variable f1 y a la variable f2. ¿Qué valor da f1(3,4)? ¿Y f2(8,7)?

  3. Crea una función calculadora(operación) donde, según el caracter en el argumento operación, te devuelva una función que realice esa operación (suma +, resta -, multiplicación x y división /). Es decir, hacer una calculadora donde especificas la operación con un caracter.

5.2. Funciones Flecha (arrow functions)

  1. Son una alternativa (compacta) para definir una función -> js_arrow_function

  2. Sólo para un uso sencillo (tienen limitaciones)

  3. Pueden tener un argumento, o varios

  4. Son muy útiles para compactar y definir funciones, ya sea directamente o que se pasan como argumentos

  5. Uso:

    1. Usan el símbolo de flecha o =>

    2. Se elimina la palabra function y return

  6. Pasas de la definición completa a la compacta (arrow function):

    1. Eliminas la palabra function

    2. Eliminas las llaves {} donde defines el cuerpo de la función

    3. Eliminas la palabra return

    4. Eliminas los paréntesis (ojo que sólo si tienes un argumento)

  7. Son funciones anónimas (no tienen nombre), salvo que hagas una asignación. Por ejemplo

    const mi-funcion = (a,b) => a + b *6;
    

Actividad T05-A02. Uso de funciones flecha

  1. Usa funciones flecha en el ejemplo de la calculadora de la sesión anterior

5.3. Callbacks (funciones llamadas dentro de funciones)

  1. Es un concepto genérico( Callback-Retrollamada )

    1. Llamamos a una función A, que ejecuta a otra función B que le pasamos como parámetro de entrada

    2. Puede ser llamada de forma síncrona o asíncrona

    3. La mayoría de lenguajes lo soportan, cada uno de maneras diferentes.

  2. Usamos las funciones como elementos de primer orden (objetos)

  3. Ya lo usamos al añadir manejadores de eventos a elementos del DOM (si usas addEventListener)

  4. Algunos objetos tienen métodos que permiten usar funciones como argumentos (callback). Por ejemplo:

    1. Window/setTimeout. Para ejecutar una función al finalizar un temporizador

    2. Window/setInterval. Para ejecutar una función de forma continua

    3. EventTarget/addEventListener. Para ejecutar una función después de la ocurrencia de un evento

Actividad T05-A03. Ejercicios con funciones callback

  1. ¿Cómo modificarías el ejemplo de la calculadora usando funciones callback?

  2. Realiza el ejemplo del video usando Window/setTimeout

    1. Ejecuta una función una detrás de otra

    2. Ejecuta las funciones en formas diferentes

  3. Realiza un pequeño juego ( por ejemplo ):

    1. Tengo un juego con varios personajes

    2. que se pueden atacar con diferentes armas

    3. Atacar es la función principal (o método de un objeto personaje)

    4. y usan diferentes armas (que en realidad son funciones)

    5. Y podrías añadir diferentes armas (y formas de atacar) sin modificar (mucho) la estructura principal.


5.4. Funciones Map, Reduce, Filter

  1. Tres muy habituales en programación funcional:

    1. Map . Crea un array nuevo, donde cada elemento nuevo es el resultado de una función sobre el elemento antiguo

    2. Filter . Crea un array nuevo con los elementos que cumplan una condición

    3. Reduce .

      1. Opción más compleja para generar un valor resultado de ejecutar una función sobre los elementos de un array

      2. Más complejo de entender pero puede ser útil en algunos escenarios complejos

  2. Y puede trabajar sobre objetos JS

    1. Las llaves se encierran en paréntesis cuando se usan objetos

    2. Eso permite usarlo a medida para procesar datos de un objeto

Actividad T05-A04. Ejercicios con funciones map, reduce y filter

Supongamos que tenemos el array a = [2,5,7, 9, 11,20, 50]. Resuelve los siguientes problemas:

  1. Devuelve un array con los mismos elementos de a pero multiplicados por 2

  2. Devuelve un array con los mismos elementos de a pero aplicandole la función f1. La función f1 le suma 4 al argumento de entrada

  3. Devuelve un array con los elementos de a mayores de 10

  4. Devuelve un array con los elementos de a que cumplan la función f2. La función f2 revisa si el argumento de entrada, multiplicado po2 en menor que 20.

  5. Devuelve la suma de todos los números del array

  6. Devuelve la suma de todos los números del array pero añadiendole 100. Es decir, no empieza en cero

  7. Devuelve un valor que en realidad es el cálculo de la función f3. f3 es una función que devuelve la diferencia entre dos valores.

5.5. Asincronía en JS ( Event Loop )

  1. El paradigma (por ejemplo la programación funcional) es una cosa y …

  2. … otra la concurrencia de los procesos (o sea la programación síncrona o asíncrona)

  3. JS: es Asíncrono y Concurrente

    1. Síncrono/Asíncrono: En qué orden ejecuto los procesos (y si tengo que esperar a que terminen)

    2. Concurrente/Parelelo: Quien ejecuta los procesos y en qué momento

    3. JS: sólo se ejecuta una función a la vez (concurrente) y los gestiona de forma asíncrona

  4. Coordinación de la ejecución asíncrona y concurrente: (Event Loop)

    1. Ejecutar procesos

    2. Atender eventos (capturar y procesar)

    3. Ejecutar procesos que están esperando (en cola)

  5. Elementos:

    1. Stack. Una pila de tareas/procesos, a medida que se van ejecutando se va llenando

    2. Heap. Un montón de objetos que están en memoria disponibles para ejecutar

    3. Queue. Entra un mensaje (llamada a función) y se ejecuta hasta finalizar (run-until-completion)

  6. Inconvenientes:

    1. Una función podría bloquear la ejecución (y se bloquea la interacción con el usuario)

    2. Para tareas con mucha demanda de ejecución (cálculos por ejemplo), este modelo no funciona bien

    3. Simula la sincronía, es decir, no se puede garantizar que una función se ejecuta en el momento exacto que quieres

Actividad T05-A05. Entender los conceptos del Event Loop

Juega con la herramienta Loupe . Tiene un código predeterminado pero puedes por ejemplo crear uno:

  1. Un botón en HTML con …

  2. un evento «click» que lance una función después de un retardo (setTimeout)

  3. un evento «keydown» que lance una función cuando pulses una tecla

  4. y … lo que se te ocurra.

Y viendo la simulación puedes tratar de responder las siguientes preguntas:

  1. En qué orden se ejecutan las funciones

  2. ¿Hay algúna función que se ejecute de forma asíncrona?

  3. ¿Qué pasa si hago click en el botón?

  4. ¿Y si hago click 3 veces?

  5. ¿Qué paso si pulso una tecla?

  6. ¿Y si la pulso varias veces?

  7. ¿Por qué elementos del event loop pasan las funciones que se ejecutan?

5.6. Promesas

  1. El problema de demasiadas llamadas dentro de llamadas (callback nesting):

  2. Usando Promesas :

    1. Resuelven el problema del anidamiento (nesting)

    2. Recuperan el control de la ejecución

    3. Es un objeto (Global_Objects/Promise) que devuelve un objeto Promise

    4. con un resultado cuando esté listo (promete hacerlo), mientras pasa por unos estados (pending / fullfilled / rejected) y

      https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/promises.png
    5. tiene una serie de métodos para acceder al resultado (o al error)

Actividad T05-A06. Ejercicios con promesas

Crear un programa que simule un juego en el que se lanzan dos dados. Ganará el número más pequeño.

5.7. Agrupar Promesas

  1. Puedo agrupar promesas e invocar varias a la vez (que no dependan unas de otras)

  2. Evolución en JS de la programación asíncrona (en realidad es lo mismo, pero mejor presentado):

    1. async Declaro que esa función va a devolver un objeto Promise y que puedo usar await dentro del cuerpo de la función

    2. await . Es un operador que se usa para esperar a que se resuelva una promesa, y devuelve el valor

Actividad T05-A07. Crear un juego sencillo de dados

Crea un programa que simule un juego entre dos jugadores, en el que lanzan 3 dados cada uno. Gana el que sume el menor valor entre los tres.

5.8. AJAX moderno: El API Fetch

  1. El API Fetch

    1. Peticiones HTTP usando promesas y de forma más eficiente

    2. Define una interfaz para gestionar el mensaje HTTP: Request y Response

    3. Integrada en el navegador y recomendada para aglutinar las peticiones HTTP en diferentes componentes

  2. El uso es sencillo, y a la vez permite mucha flexibilidad :

    1. Defines el url (y si quieres el objeto Request con personalizacion de la petición)

    2. Llamas a la función fetch del objeto window y te devolverá una promesa (de conexión)

    3. Diseñas el encadenamiento de peticiones (y control de errores si necesitas)

  3. Política CORS (Cross Origin Resource Sharing)

    1. Se define quien puede acceder a recursos cruzados entre dominios

    2. Se podría modificar la cabecera Access Headers/Access-Control-Allow-Origin

    3. De forma predeterminada, para solicitudes asíncronas sólo podrías hacerlo al mismo dominio (cliente y servidor)

Actividad T05-A08. Refactorizar Ejercicio AJAX

Refactoriza el ejercicio final de AJAX, usando el Fetch API.

¿Podrías hacer una aplicación web que revise el calendario del mundial de Qatar ? Lo que me gustaría es:

  1. Seleccionar un equipo y que me diga qué día y a qué hora juega

  2. Seleccionar un partido y que me diga el resultado

  3. Seleccionar un día y que me diga qué partidos hay