DevHub Global Solutions | Educativo

Promesas y async/await: manejo de operaciones asíncronas

Domina el manejo de operaciones asíncronas en JavaScript con Promesas y async/await. Aprende desde conceptos fundamentales hasta patrones avanzados para controlar flujos asíncronos complejos con código limpio y mantenible.
Promesas y async/await: manejo de operaciones asíncronas
Diagrama de flujo de ejecución asíncrona con promesas

Fundamentos de Promesas

Las promesas representan operaciones asíncronas:

Estados

Pending, Fulfilled, Rejected

Encadenamiento

.then().catch().finally()

Asíncrono

No bloquea el hilo principal

// Crear una promesa
const miPromesa = new Promise((resolve, reject) => {
  // Operación asíncrona
  setTimeout(() => {
    const exito = true; // Simular resultado
    if (exito) {
      resolve('Datos obtenidos');
    } else {
      reject(new Error('Fallo en la operación'));
    }
  }, 1000);
});

// Consumir promesa
miPromesa
  .then(resultado => {
    console.log(resultado);
  })
  .catch(error => {
    console.error(error);
  })
  .finally(() => {
    console.log('Operación finalizada');
  });

Async/Await: Sintaxis Moderna

Azúcar sintáctico para trabajar con promesas:

// Función async devuelve una promesa
async function obtenerDatos() {
  try {
    const respuesta = await fetch('https://api.ejemplo.com/data');
    if (!respuesta.ok) {
      throw new Error('Error en la respuesta');
    }
    const datos = await respuesta.json();
    return datos;
  } catch (error) {
    console.error('Error al obtener datos:', error);
    throw error; // Relanzar para manejo superior
  }
}

// Uso
(async () => {
  try {
    const datos = await obtenerDatos();
    console.log(datos);
  } catch (error) {
    // Manejar error
  }
})();

async/await permite escribir código asíncrono con estructura síncrona

Patrones Avanzados

Técnicas para flujos asíncronos complejos:

// Ejecución paralela
const [usuario, posts] = await Promise.all([
  fetch('/usuario/1').then(r => r.json()),
  fetch('/usuario/1/posts').then(r => r.json())
]);

// Timeout con Promise.race
async function fetchConTimeout(url, timeout = 5000) {
  const fetchPromise = fetch(url);
  const timeoutPromise = new Promise((_, reject) => {
    setTimeout(() => reject(new Error('Timeout')), timeout);
  });
  
  return Promise.race([fetchPromise, timeoutPromise]);
}

// Secuencia con for...of
async function procesarElementos(elementos) {
  const resultados = [];
  
  for (const elemento of elementos) {
    const resultado = await procesar(elemento);
    resultados.push(resultado);
  }
  
  return resultados;
}
Patrón Implementación Caso de uso
Paralelo Promise.all() Operaciones independientes
Carrera Promise.race() Timeout o primera respuesta
Secuencial async/await en bucle Operaciones dependientes
Settled Promise.allSettled() Necesidad de todos los resultados

Manejo de Errores Profundo

Estrategias robustas para errores asíncronos:

// Patrón de función segura
function asyncHandler(fn) {
  return async (...args) => {
    try {
      return await fn(...args);
    } catch (error) {
      // Manejo centralizado de errores
      logError(error);
      showUserNotification('Error en la operación');
      throw error; // Opcional
    }
  };
}

// Uso
const obtenerDatosSeguro = asyncHandler(obtenerDatos);

// Errores en paralelo
async function fetchMultiple(urls) {
  const resultados = await Promise.allSettled(
    urls.map(url => fetch(url))
  );
  
  const exitosos = resultados
    .filter(r => r.status === 'fulfilled')
    .map(r => r.value);
    
  const fallidos = resultados
    .filter(r => r.status === 'rejected')
    .map(r => r.reason);
    
  return { exitosos, fallidos };
}
AM

Sobre el autor

Arquitecta JavaScript con 10 años de experiencia. Especialista en programación asíncrona y autora de 'Asynchronous JavaScript Patterns'.