Nivel inicial7 min de lectura · Publicado el

Programación asíncrona en JavaScript y AJAX, Carlos Blé

Programación asíncrona en JavaScript: pides los datos, el código sigue y, al llegar la respuesta, se ejecuta el callback; el test espera. Asíncrono: pides y siguesrubentejera.com 1Pides los datos2Sigues con otras cosas3Llegan: el callbacktest:awaitespera, luego comprueba
Pides los datos (1) y el programa sigue con otras cosas (2). Cuando llega la respuesta se ejecuta el callback (3). Por eso el test usa await: si no espera, termina antes de comprobar nada y puede dar por bueno código que falla.

Quién es Carlos Blé y qué son estos vídeos

Carlos Blé es programador y formador, autor de Diseño Ágil con TDD, que en 2010 fue el primer libro sobre TDD escrito en castellano. Estos vídeos no son un curso editado: son grabaciones de dos clases con un grupo de alumnos (la Generación K), subidas a su canal «Carlitos y sus cosas». Por eso tienen ritmo de clase, con dudas y repasos incluidos.

Los dos vídeos

1. Introducción a AJAX y testing asíncrono

Unos 85 minutos. Según su descripción, se ve cómo hacer una petición AJAX al backend, la diferencia entre programación síncrona y asíncrona, y cómo simular las llamadas GET al backend en los tests unitarios.

2. AJAX, callbacks y dificultades del testing de integración

Unos 56 minutos. Resuelve dudas de la sesión anterior y repasa las llamadas AJAX al servidor, los callbacks y el testing síncrono y asíncrono.

Cómo sacarle partido

  1. Lee primero «La idea, en dos minutos», aquí abajo, para llegar al vídeo con el concepto claro.
  2. Ve el primer vídeo con un editor abierto y repite cada ejemplo a la vez. Puedes subir la velocidad en las partes de dudas.
  3. Antes del segundo vídeo, intenta escribir tú un test de una función que pida datos, sin red.
  4. Termina pasando el ejemplo a fetch y async/await, como el de este artículo.

La idea, en dos minutos

Pides unos datos al servidor. Tu programa no se queda parado esperando: sigue con otras cosas y, cuando llega la respuesta, se ejecuta lo que dejaste preparado. Eso es lo asíncrono.

AJAX es el nombre clásico de pedir datos al servidor desde la página sin recargarla. Y el callback es el «llámame cuando esté listo»: una función que se ejecuta cuando llega la respuesta.

console.log('1. Pido los datos');
setTimeout(() => console.log('3. Llegan los datos'), 0);
console.log('2. Sigo con otras cosas');

Aunque la espera sea de 0 milisegundos, el orden de la salida es 1, 2, 3: el callback espera su turno.

El mismo ejemplo, con JavaScript actual

En 2018 era habitual XMLHttpRequest o $.ajax de jQuery con callbacks. Hoy los navegadores y Node traen fetch, que devuelve una promesa, y await permite escribir el código asíncrono como si fuera de arriba abajo.

// usuarios.mjs
export async function nombreDeUsuario(id, pedir = fetch) {
  const respuesta = await pedir(`/api/usuarios/${id}`);
  if (!respuesta.ok) throw new Error(`Error ${respuesta.status}`);
  const usuario = await respuesta.json();
  return usuario.nombre;
}

La función recibe pedir como parámetro. En producción es fetch; en el test recibe una versión falsa. Así el test no depende de la red, que es justo la dificultad que tratan los vídeos.

// usuarios.test.mjs
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { nombreDeUsuario } from './usuarios.mjs';

test('devuelve el nombre que envía el servidor', async () => {
  const pedirFalso = async () => ({ ok: true, json: async () => ({ nombre: 'Ana' }) });
  assert.equal(await nombreDeUsuario(1, pedirFalso), 'Ana');
});

test('falla si el servidor responde con error', async () => {
  const pedirFalso = async () => ({ ok: false, status: 404 });
  await assert.rejects(nombreDeUsuario(99, pedirFalso), /Error 404/);
});
node --test usuarios.test.mjs
ℹ tests 2
ℹ pass 2
ℹ fail 0

Por ejemplo, este test espera un error 500, pero el servidor falso responde con un 404. Sin el await:

test('falla si el servidor responde con error', async () => {
  const pedirFalso = async () => ({ ok: false, status: 404 });
  assert.rejects(nombreDeUsuario(99, pedirFalso), /Error 500/); // falta el await
});
✔ falla si el servidor responde con error (1.179552ms)
ℹ Error: Test "falla si el servidor responde con error" at sin-await.test.mjs:5:1 generated asynchronous activity after the test ended. This activity created the error "AssertionError [ERR_ASSERTION]: The input did not match the regular expression /Error 500/. Input:

'Error: Error 404'
" and would have caused the test to fail, but instead triggered an unhandledRejection event.
✖ sin-await.test.mjs (52.972013ms)
ℹ tests 2
ℹ suites 0
ℹ pass 1
ℹ fail 1
…

Con el await, el mismo test sale en rojo, como debe.

Si tu test necesita la red, aún no es un test unitario.

Para quién es y lo que conviene saber

Te sirven si ya sabes lo básico de JavaScript (variables, funciones, objetos) y te cuesta entender por qué el código no se ejecuta en el orden en que lo lees, o cómo probar algo que depende del servidor. Si nunca has programado, empieza antes por lo básico del lenguaje.

Ten en cuenta que son de 2018: las ideas (asincronía, callbacks, aislar el test de la red) siguen igual, pero la sintaxis para pedir datos ha cambiado. Por eso tienes arriba la versión actual.

Alternativas

Carlos Blé tiene más vídeos de esa serie, como el de this en JavaScript. Si quieres profundizar en los dobles de prueba, prueba la kata de stubs y spies.

Fuentes

Comprobado el 7 de noviembre de 2026: