1.1. Fundamentos de fetch, promesas y async/await
Para poder trabajar con los datasets del portal de Datos Abiertos de la Junta de Castilla y León, necesitamos una herramienta que nos permita traer información externa a nuestras aplicaciones web.
En JavaScript, esa herramienta es fetch, el método moderno y estándar para realizar peticiones HTTP desde el navegador.
📌 ¿Qué es fetch?
fetch(url) es una función nativa que realiza una solicitud al servidor indicado y devuelve una promesa.
Esa promesa se resuelve en un objeto de tipo Response, que encapsula tanto el estado de la petición como los datos obtenidos.
Características clave:
- Es parte del estándar web (no requiere instalar librerías).
- Sustituye a la antigua API
XMLHttpRequest, con una sintaxis más clara y potente. - Permite trabajar con distintos formatos: JSON, CSV (como texto), XML, imágenes, binarios, etc.
📌 Sintaxis básica
fetch("datasets/json/marcas-calidad.json")
.then(respuesta => {
if (!respuesta.ok) throw new Error("HTTP " + respuesta.status);
return respuesta.json();
})
.then(datos => {
console.log("Datos recibidos:", datos);
})
.catch(error => {
console.error("Error en la petición:", error);
});
En este ejemplo:
fetch(...)inicia la petición.- El primer
.then()recibe un objetoResponsey lo convierte a JSON. - El segundo
.then()procesa los datos ya transformados. .catch()captura cualquier error de red o de procesamiento.
📌 El objeto Response
Cuando fetch responde, lo primero que obtenemos es un objeto Response.
Este objeto nos da acceso a:
status→ código HTTP (200éxito,404no encontrado,500error interno).ok→ booleano que indica si la petición se resolvió correctamente (truesistatus∈ 200–299).headers→ lista de cabeceras HTTP de la respuesta.
Y, lo más importante, métodos para acceder al cuerpo de la respuesta:
.json()→ interpreta el cuerpo como JSON..text()→ devuelve el cuerpo como texto plano (CSV, XML…)..blob()→ devuelve datos binarios (imágenes, PDF)..arrayBuffer()→ acceso de bajo nivel a datos binarios.
📌 Uso con async/await
El mismo ejemplo anterior puede escribirse de forma más clara con async/await:
async function cargarDatos() {
try {
let respuesta = await fetch("datasets/xml/eventos.xml");
if (!respuesta.ok) throw new Error("HTTP " + respuesta.status);
let texto = await respuesta.text();
console.log("Contenido del XML:", texto);
} catch (error) {
console.error("Error en la carga:", error);
}
}
Ventajas de async/await:
- El código se lee “de arriba a abajo”, como si fuera síncrono.
- El bloque
try/catchcentraliza el manejo de errores. - Facilita la comprensión en programas más largos con varias peticiones.
📌 Ejemplos prácticos
1. Cargar y mostrar un JSON
async function cargarMarcas() {
let res = await fetch("datasets/json/marcas-calidad.json");
if (!res.ok) throw new Error("HTTP " + res.status);
let datos = await res.json();
console.log("Listado de marcas:", datos);
}
2. Cargar un CSV como texto
async function cargarCSV() {
let res = await fetch("datasets/csv/hosteleria-a-domicilio.csv");
let texto = await res.text();
let lineas = texto.trim().split("\n");
console.log("Número de registros:", lineas.length - 1);
}
3. Descargar y mostrar una imagen
async function cargarImagen() {
let res = await fetch("imagenes/logo.png");
let blob = await res.blob();
document.getElementById("logo").src = URL.createObjectURL(blob);
}
<img id="logo" alt="Imagen cargada con fetch">
📌 Opciones avanzadas de fetch
Además de descargar datos, fetch permite enviar información al servidor.
Ejemplo de envío de un objeto JSON:
fetch("https://ejemplo.com/api/usuarios", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ nombre: "Laura", activo: true })
});
Opciones más comunes:
method: tipo de petición (GET,POST,PUT,DELETE).headers: añadir cabeceras HTTP (ej.Content-Type).body: datos enviados (normalmente en JSON oFormData).
📌 Limitaciones y retos
Aunque fetch es muy potente y hoy en día es el estándar para trabajar con datos en la web, conviene ser conscientes de algunas limitaciones prácticas:
- Errores HTTP:
fetchno lanza una excepción cuando la respuesta es un404o un500. El objetoResponsesigue devolviéndose como válido y solo sabremos que algo fue mal si comprobamos la propiedadres.oko el código de estado. Esto obliga a incluir siempre una comprobación explícita. - Restricciones CORS: por motivos de seguridad, un navegador no puede acceder a datos de cualquier servidor libremente. El propio servidor tiene que declarar que permite ser consumido desde otros orígenes. Si no, veremos el típico error de CORS policy en consola.
- Protocolos seguros: cuando nuestra página se carga en
https://, el navegador bloquea cualquier petición ahttp://porque lo considera inseguro. Por eso, en proyectos reales hay que asegurarse de que todas las fuentes de datos estén publicadas en HTTPS. - Acceso local: abrir un archivo directamente con
file://no funciona, ya que los navegadores bloquean estas lecturas por seguridad. Siempre debemos trabajar con un servidor local como Live Server,mkdocs serveo un servidor integrado. - Control de tiempo de espera:
fetchno incorpora un sistema de timeout. Si un servidor tarda demasiado en responder, la petición se queda bloqueada hasta que se cierre. Para evitarlo, es recomendable usarAbortControllery definir un límite de tiempo.
📌 Ventajas
A pesar de esas limitaciones, fetch se ha convertido en el método estándar porque ofrece grandes ventajas frente a alternativas anteriores como XMLHttpRequest:
- API moderna y nativa: forma parte del propio lenguaje y no requiere librerías externas, lo que simplifica el desarrollo.
- Compatibilidad universal: está soportado en todos los navegadores modernos, lo que asegura que el código funcionará en cualquier entorno actual.
- Sintaxis más clara: su diseño basado en promesas y la posibilidad de usar
async/awaithacen que el código sea más legible y fácil de mantener. - Versatilidad: permite trabajar con prácticamente cualquier recurso: JSON, texto plano, XML, imágenes o incluso archivos binarios complejos, adaptándose a distintos escenarios.
En conjunto, fetch combina simplicidad, potencia y estandarización, lo que lo convierte en la herramienta ideal para aprender y trabajar con datos abiertos en aplicaciones web.
Consejo práctico
Piensa en fetch como un proceso en dos fases:
1. Hacer la petición y obtener un objeto Response.
2. Transformar la respuesta al formato correcto (.json(), .text(), .blob()).
Revisar la documentación de los datasets es fundamental para saber qué método usar.
📝 Preguntas de repaso
Repaso
- ¿Qué devuelve
fetch()y qué representa? - ¿Qué diferencia hay entre el objeto
Responsey los datos obtenidos con.json()o.text()? - ¿Qué ventajas tiene escribir con
async/awaitfrente a encadenar.then()? - ¿Por qué es necesario comprobar siempre
res.oktras una petición? - ¿Qué problemas pueden surgir si trabajamos con datos desde
file://en lugar de un servidor local?