Files
etsii-vault/SEGUNDO/IISSI2/Teoría_2324.md
2024-10-10 09:10:04 +02:00

13 KiB

TEMA 9: Programación asíncrona y buenas prácticas

1. Programación síncrona/asíncrona

JavaScript es single-threaded y en principio síncrono. También puede tener comportamiento asíncrono (para por ejemplo consultar APIs). Soluciones asíncronas: callback, promises, async/await...

  • Comunicación síncrona (o bloqueante): Cuando hay comunicación síncrona entre dos entes A y B, si A envía un mensaje a B, deja de actuar hasta que B responde.
  • Comunicación asíncrona (o no bloqueante): Cuando hay comunicación asíncrona entre dos entes A y B, si A envía un mensaje a B, puede seguir actuando y B responderá cuando pueda.

- Funciones callback

Una función callback es una función que se pasa como parámetro. !Pasted image 20240312153525.png Generalmente se usan para definir el código asociado a un evento (por ejemplo un botón cuando se haga click en él). !Pasted image 20240312153619.png

- Promises

Antes se usaba un objeto tipo Promise para gestionar llamadas asíncronas. La promesa llamaba a una función callback ("then") cuando la operación asíncrona finalizaba con éxito, y a otra diferente ("catch") si fallaba. Como no es muy intuitivo, se introdujo en 2017 async/await.

- Async/await

!Pasted image 20240312154046.png En un comportamiento síncrono, hasta que la API no responda no carga la página completa y se queda bloqueada "cargando". Con async/await, se puede solucionar esto convirtiendo las funciones en asíncronas. Las funciones marcadas con async se ejecutarán de forma paralela al hilo principal. !Pasted image 20240312154300.png Usando await se espera a la respuesta de la API, y se convierte en bloqueante, pero loadPhotos() sigue siendo asíncrona. !Pasted image 20240312154500.png

2. Buenas prácticas

- Consideraciones generales

  • Usar siempre ; tras cada instrucción.
  • Usar let para declarar variables en vez de var;
  • Usar notación camelCase.
  • Usar {} en lugar de new Object() y [] en lugar de new Array().
  • Usar siempre el mismo tipo de comillas, salvo casos excepcionales.
  • Usar siempre la misma unidad de identación (4 espacios/1 tab).
  • No confundir for...of para iterar arrays con for...in para iterar claves.
  • Usar el comparador de igualdad === en lugar de == (y !== en vez de !=).

- Modo estricto

  • Usar siempre el modo estricto ("use strict";):
    • Impide usar variables no declaradas.
    • Impide que se pueda cambiar valores de elementos NaN o Infinity.
    • Impide definir un Object con valores repetidos.
    • Convierte en errores cosas que generalmente serían warnings.

- Puntos de entrada

- Módulos

Los módulos permiten importar y exportar funciones y variables de otros módulos. Se recomienda su uso ya que, si no, todo lo que sea definido globalmente en un archivo JS será accesible desde cualquier otro archivo. Sólo es necesario enlazar un script (B) en el HTML ya que las sentencias import/export se encargan de cargar automáticamente el resto de archivos (A u otros) JS referenciados.

- Organización del código

!Pasted image 20240312155900.png

  • La carpeta js contendrá todo el código JS incluidas las vistas (controladores para archivos html, ej. index.html -> index.js).
  • La carpeta api contiene los módulos que se encargan de la comunicación con los endpoints de la API.
  • La carpeta libs contiene librerías JS externas que usemos.
  • La carpeta renderers contiene módulos para transformar objetos JS en entidades HTML.
  • La carpeta utils contiene módulos con funciones de utilidad (como include(), o parseHTML()).
  • La carpeta validators contiene módulos cuya función es validar datos recibidos en forms.

TEMA 10: Manipulación del DOM y renders

1. Modelo DOM (Document Object Model)

Modelo que se crea al cargar una página en el navegador. Contiene una jerarquía de elementos en forma de árbol. Con JS se puede:

  • Cambiar los elementos HTML de la página
  • Cambiar los valores de los atributos de dichos elementos
  • Cambiar los estilos CSS asociados a los elementos Eliminar elementos y atributos existentes en el HTML
  • Añadir nuevos elementos y atributos HTML
  • Ejecutar funciones y scripts en respuesta a los eventos originados en los elementos HTML
  • Crear nuevos manejadores de eventos
  • Eliminar manejadores de eventos En el DOM cada objeto es un nodo (node). Cada nodo tiene padre, excepto el raíz. Cada nodo puede tener n hijos. Si dos nodos tienen el mismo padre son hermanos. !Pasted image 20240319154406.png

2. Manipulación del DOM

DOM ofrece una API con métodos y propiedades para manipular elementos HTML. El primer paso es encontrar el elemento y a partir de ahí modificar. Algunos métodos son:

  • node.getElementById(id): Obtiene un elemento a partir de su ID.
  • node.getElementsByTagName(tagName): Obtiene un array de descendientes del nodo que sean de un tipo de etiqueta.
  • node.getElementsByClassName(className): Obtiene un array de descendientes del nodo con una clase determinada.
  • node.querySelectorAll(cssSelector): Obtiene un array de descendientes del nodo que concuerdan con un selector CSS.
  • node.classList: Devuelve la lista de clases del nodo (mutable).
  • node.tagName: Devuelve el tipo de etiqueta HTML del nodo.
  • node.style: Proporciona acceso para modificar y consultar los estilos.
  • node.innerHTML: Devuelve y permite modificar el contenido HTML de un nodo.
  • node.innerText: Devuelve y permite modificar el texto de un nodo.
  • node.getAttribute("atributo"): Permite consultar el valor de un atributo del nodo.
  • node.setAttribute(nombreAtributo, valor): Modifica el valor de un atributo.
  • document.createElement(nombreElemento): Crea un nuevo elemento HTML.
  • node.removeChild(elemento): Elimina un nodo hijo.
  • node.remove(): Elimina el nodo.
  • node.append(elemento): Añade un elemento como último hijo.
  • node.prepend(elemento): Añade un elemento como primer hijo.
  • node.insertBefore(elemento, hermano): Añade un elemento como nodo hijo, por delante de un nodo hermano.
  • node.replaceChild(nuevo, antiguo): Reemplaza un nodo hijo con otro.
  • node.parentNode: Devuelve el nodo padre.
  • node.firstChild: Devuelve el primer hijo del nodo.
  • node.lastChild: Devuelve el último hijo del nodo.
  • node.childNodes[i]: Devuelve el i-ésimo hijo del array de hijos del nodo.
  • node.nextSibling: Devuelve el siguiente hermano de un nodo.
  • node.previousSibling: Devuelve el hermano anterior de un nodo. El DOM tiene varias propiedades extra como:
  • document.URL
  • document.body
  • document.cookie
  • document.doctype
  • document.head
  • document.inputEncoding
  • document.readyState
  • document.title

- NodeLists

Hay propiedades para acceder directamente a colecciones de objetos:

  • document.images: Todas las imágenes del documento.
  • document.forms: Todos los formularios del documento.
  • document.forms[X].elements: Todos los campos del formulario X.
  • document.links: Todos los <a> del documento.
  • document.scripts: Todos los scripts.

3. Renderizadores

Normalmente se necesita mostrar muchos elementos del mismo tipo, como imágenes o mensajes de éxito/error. O mostrar el mismo elemento de más de una forma diferente (miniatura o completa).

TEMA 12: Llamadas AJAX mediante REST y JSON

1. REST

Arquitectura cliente-servidor. No tiene estado ya que se basa en HTTP. Cacheable. Modelo en capas. !Pasted image 20240409154435.png

2. Formatos de comunicación JSON

!Pasted image 20240409154700.png

- Tipos de datos

  • Number: números decimales con signo, incluyendo notación exponencial.
  • Array: elementos separados por "," y entre "[ ]". Pueden ser de cualquier tipo.
  • String: secuencia de caracteres entre "". Los caracteres especiales se escapan con "\".
  • Object: colección no ordenada de pares K,V entre "{ }" y separados por ",".
  • null: valores vacíos. Undefined en JS.
  • Boolean: true/false.

3. Implementación de llamadas asíncronas REST

- AJAX (Asynchronous JavaScript And XML)

Inicialmente se usaba XML pero ahora JSON. El núcleo de AJAX es la API XMLHttpRequest o XHR. Algunas implementaciones de AJAX son XHR, fetch (nativas), jQuery, axios (externas).

- Fetch

API nativa basada en Promises. La respuesta es una Promise. Cuando se resuelve la Promise se puede consultar el objeto Response.

- jQuery

La librería incluye diversos métodos para AJAX. Basada en XHR. Facilita el código y es cross-browser pero es externa, y se usa FormData.

- Axios

Basada en XHR pero usa funciones asíncronas. Como ventajas:

  • Intercepta request y response (permite examinar y modificar las peticiones y respuestas HTTP).
  • Permite cancelar requests.
  • Múltiples librerías de terceros como "addons".
  • Compatibilidad con muchos navegadores.
  • Simplifica la lógica de gestión de respuestas y errores.
  • Muy popular actualmente (incluso con Node.js). La única desventaja es que es externa.

NOTA: Al capturar errores hay que capturar error.response.data.message en el catch y no solo el objeto error.

4. Módulos API

  • /js/api/common.js: URL Base y configuración común para todas las peticiones.
  • /js/api/OBJETO.js: módulo de acceso a API para un OBJETO (ej. Fotos).

TEMA 13: Persistencia en cliente

1. HTTP Cookies

Una cookie HTTP (o web cookies, Internet cookies, browser cookies) es un pequeño fragmento de información enviado desde un sitio web y que el navegador almacena en local mientras este navega por el sitio. !Pasted image 20240423154342.png

  • Cookies de sesión (in-memory, transient, non-persistent): Son volátiles y se almacenan en memoria y se borran al cerrar el navegador. No suelen tener fecha de expiración.
  • Cookies persistentes (tracking): Se almacenan incluso con el navegador cerrado. Tienen fecha de expiración. Hay distintos tipos según su origen:
  • First-party cookies: Las envía el sitio web que el usuario visita.
  • Third-party cookie: Las envía un sitio web externo al visitado (likes, adSense, iframes). Hay varios metadatos, como Domain, Path, Same-site, Secure, HTTPOnly, Max-Age, Size. Las cookies tienen varias finalidades como gestionar sesiones (productos añadidos al carrito, puntuaciones de juegos, auth cookies), tracking (páginas visitadas, datos de formularios, estadísticas) o preferencias del usuario (lenguaje, colores, divisa).

- Problemas de seguridad

Las cookies forman parte de las request, por lo que hay que validarlas y contemplar la posibilidad de que formen parte de un ataque. Nunca se debe almacenar información sensible. Las third party cookies se pueden usar para tracking o para ataques XSRF. Sin embargo pueden ser útiles para integrar componentes de un sitio en otro (google maps, youtube, etc).

2. Web Storage API

Permite al navegador almacenar pares clave/valor de forma más intuitiva. Más seguro que las cookies. Permite mayor tamaño de almacenamiento.

- SessionStorage

Mantiene un área de almacenamiento separada para cada origen mientras el navegador esté abierto. Cuando se cierra se borran los datos. El límite es 5MB. Accesible mediante Window.sessionStorage.

- LocalStorage

Mantiene un área de almacenamiento separada para cada origen incluso al cerrar el navegador. Almacena datos sin fecha de expiración o y sólo se borra mediante JS o borrando el caché del navegador. Límite 5MB. Accesible mediante Window.localStorage.

3. Cache API