JavaScript

JavaScript

Tutorial JavaScript: Promises

JavaScript promises: manejo de asincronía. Domina el manejo de asincronía en JavaScript utilizando promises con ejemplos detallados.

Aprende JavaScript y certifícate

Estados y ciclo de vida: Pending, fulfilled y rejected en el flujo de una promesa

Las promesas en JavaScript representan operaciones asíncronas que pueden completarse en algún momento futuro. Cada promesa atraviesa diferentes estados durante su ciclo de vida, lo que permite gestionar de manera elegante el flujo de ejecución asíncrono.

Estados fundamentales de una promesa

Una promesa siempre se encuentra en uno de estos tres estados:

  • Pending (pendiente): Estado inicial cuando se crea la promesa. La operación asíncrona aún no se ha completado ni ha fallado.
  • Fulfilled (cumplida): La operación asíncrona se completó exitosamente.
  • Rejected (rechazada): La operación asíncrona falló por algún motivo.

Las promesas que han sido resueltas (fulfilled) o rechazadas (rejected) se consideran settled (establecidas), lo que significa que han alcanzado un estado final y no pueden cambiar a otro estado.

Creación de una promesa

Para crear una promesa, utilizamos el constructor Promise que recibe una función ejecutora con dos parámetros: resolve y reject:

const myPromise = new Promise((resolve, reject) => {
  // Operación asíncrona
  const success = true;
  
  if (success) {
    resolve('Operation completed successfully');  // Cambia a fulfilled
  } else {
    reject(new Error('Operation failed'));  // Cambia a rejected
  }
});

En este ejemplo, la promesa comienza en estado pending y, dependiendo del resultado de la operación, cambiará a fulfilled o rejected.

Visualización del ciclo de vida

Podemos observar los cambios de estado de una promesa mediante un ejemplo práctico:

console.log('Creating promise...');

const loadUserData = new Promise((resolve, reject) => {
  console.log('Promise state: PENDING');
  
  setTimeout(() => {
    const randomSuccess = Math.random() > 0.3;
    
    if (randomSuccess) {
      console.log('Promise state: about to be FULFILLED');
      resolve({ id: 1, name: 'John Doe' });
    } else {
      console.log('Promise state: about to be REJECTED');
      reject(new Error('Failed to load user data'));
    }
  }, 2000);
});

// Observamos el estado actual
console.log('Promise created, waiting for settlement...');

Este código muestra cómo una promesa permanece en estado pending durante 2 segundos antes de resolverse o rechazarse.

Transiciones de estado

Es importante entender algunas reglas clave sobre las transiciones de estado:

  • Una promesa solo puede cambiar de pending a fulfilled o de pending a rejected.
  • Una vez que una promesa está en estado fulfilled o rejected, su valor o razón de rechazo no puede cambiar.
  • Las transiciones de estado son irreversibles.

Inspección del estado actual

JavaScript no proporciona una forma directa de consultar el estado actual de una promesa, pero podemos crear una función auxiliar para demostrarlo:

function demonstratePromiseStates() {
  const promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve('Success!'), 2000);
  });
  
  // Al inicio
  logPromiseState(promise, 'Initial');
  
  // Después de 1 segundo (aún pending)
  setTimeout(() => {
    logPromiseState(promise, 'After 1 second');
  }, 1000);
  
  // Después de 3 segundos (ya fulfilled)
  setTimeout(() => {
    logPromiseState(promise, 'After 3 seconds');
  }, 3000);
  
  return promise;
}

function logPromiseState(promise, label) {
  // Truco para detectar el estado
  promise.then(
    () => console.log(`${label}: FULFILLED`),
    () => console.log(`${label}: REJECTED`)
  );
  console.log(`${label}: PENDING (if no message appears immediately)`);
}

demonstratePromiseStates();

Promesas en tiempo real

Veamos un ejemplo más práctico que simula una solicitud de red:

function fetchUserProfile(userId) {
  console.log(`Fetching user ${userId}...`);
  
  return new Promise((resolve, reject) => {
    // Simulamos una solicitud de red
    const startTime = Date.now();
    
    setTimeout(() => {
      const endTime = Date.now();
      console.log(`Network request took ${endTime - startTime}ms`);
      
      if (userId > 0) {
        resolve({
          id: userId,
          name: 'Sample User',
          email: `user${userId}@example.com`
        });
      } else {
        reject(new Error('Invalid user ID'));
      }
    }, 1500);
  });
}

// Uso
const userPromise = fetchUserProfile(42);
console.log('Promise created, application continues running...');

En este ejemplo, la promesa permanece en estado pending durante la simulación de la solicitud de red y luego cambia a fulfilled si el ID de usuario es válido o a rejected si no lo es.

Comportamiento de las promesas ya establecidas

Un aspecto interesante de las promesas es cómo se comportan cuando ya están establecidas (settled):

function createResolvedPromise() {
  return Promise.resolve('Already fulfilled');
}

const resolvedPromise = createResolvedPromise();

// Incluso si agregamos handlers después, se ejecutarán inmediatamente
setTimeout(() => {
  console.log('Adding handler to already fulfilled promise');
  resolvedPromise.then(value => {
    console.log(`Got value: ${value}`);
  });
}, 2000);

Este comportamiento es crucial para entender cómo las promesas difieren de los simples callbacks, ya que capturan un resultado que persiste y puede ser consultado en cualquier momento futuro.

Propagación de estados

El estado de una promesa puede propagarse a través de cadenas de promesas, lo que es fundamental para el encadenamiento que veremos en secciones posteriores:

const initialPromise = new Promise((resolve, reject) => {
  setTimeout(() => resolve(10), 1000);
});

// El estado fulfilled se propaga
const derivedPromise = initialPromise.then(value => {
  console.log(`Initial promise fulfilled with: ${value}`);
  return value * 2;  // Esta promesa también se cumplirá
});

// derivedPromise estará en estado pending hasta que initialPromise se resuelva

Comprender el ciclo de vida y los estados de las promesas es esencial para dominar la programación asíncrona en JavaScript, ya que forma la base para técnicas más avanzadas como el encadenamiento y la composición de operaciones asíncronas.

Encadenamiento y composición: Métodos then, catch y finally para secuencias asíncronas

El verdadero poder de las promesas en JavaScript radica en su capacidad para encadenar operaciones asíncronas de forma legible y mantenible. Los métodos then(), catch() y finally() nos permiten crear flujos de ejecución complejos sin caer en el temido "callback hell".

El método then()

El método then() es la pieza fundamental del encadenamiento de promesas. Recibe hasta dos argumentos: una función de éxito y una función de error (opcional).

const fetchData = new Promise((resolve, reject) => {
  setTimeout(() => resolve("Data received"), 1000);
});

fetchData.then(
  data => console.log(data),           // Función de éxito
  error => console.error(error)        // Función de error (opcional)
);

La característica más importante de then() es que siempre devuelve una nueva promesa, lo que permite el encadenamiento:

function getUserData(userId) {
  return fetch(`https://api.example.com/users/${userId}`)
    .then(response => {
      if (!response.ok) {
        throw new Error('Network response was not ok');
      }
      return response.json();
    });
}

getUserData(123)
  .then(userData => {
    console.log(`User name: ${userData.name}`);
    return userData.id;
  })
  .then(userId => {
    return fetch(`https://api.example.com/orders?userId=${userId}`);
  })
  .then(response => response.json())
  .then(orders => {
    console.log(`User has ${orders.length} orders`);
  });

Transformación de valores

Cada then() puede transformar el valor que recibe y pasarlo al siguiente en la cadena:

fetch('https://api.example.com/numbers')
  .then(response => response.json())
  .then(data => data.numbers)              // Extrae solo el array de números
  .then(numbers => numbers.filter(n => n % 2 === 0))  // Filtra números pares
  .then(evenNumbers => evenNumbers.map(n => n * 2))   // Duplica cada número
  .then(result => console.log(result));    // Muestra el resultado final

El método catch()

El método catch() proporciona una forma elegante de manejar errores en cualquier punto de la cadena de promesas:

fetchUserData(userId)
  .then(userData => processUserData(userData))
  .then(processedData => saveToDatabase(processedData))
  .catch(error => {
    console.error('Error in the promise chain:', error);
    return fallbackData();  // Proporciona datos alternativos
  })
  .then(finalData => {
    // Este then se ejecutará con fallbackData si hubo un error
    console.log('Final data:', finalData);
  });

Un catch() captura errores de todas las promesas anteriores en la cadena, lo que simplifica enormemente el manejo de errores. Es equivalente a usar then(null, errorHandler).

Propagación de errores

Los errores se propagan automáticamente a través de la cadena hasta encontrar un manejador de errores:

Promise.resolve(1)
  .then(value => {
    throw new Error('Something went wrong');
    // Este error saltará al catch más cercano
  })
  .then(value => {
    // Este then nunca se ejecuta debido al error anterior
    console.log('This will not run');
  })
  .catch(error => {
    console.error('Caught:', error.message);
    return 'Recovery value';
  })
  .then(value => {
    // Se ejecuta con el valor devuelto por catch
    console.log('Recovered with:', value);
  });

El método finally()

El método finally() se ejecuta independientemente de si la promesa se cumple o se rechaza, lo que lo hace ideal para tareas de limpieza:

const loadingIndicator = document.getElementById('loading');
loadingIndicator.style.display = 'block';

fetchData()
  .then(data => {
    displayData(data);
  })
  .catch(error => {
    showErrorMessage(error);
  })
  .finally(() => {
    // Esto se ejecuta siempre, sin importar el resultado
    loadingIndicator.style.display = 'none';
  });

A diferencia de then() y catch(), el método finally() no recibe ningún argumento y no puede modificar el valor que se está propagando a través de la cadena.

Patrones de encadenamiento avanzados

Ejecución secuencial

Cuando necesitamos ejecutar operaciones asíncronas en secuencia, donde cada una depende del resultado de la anterior:

function sequentialFetch(urls) {
  let results = [];
  
  return urls.reduce((promise, url) => {
    return promise
      .then(() => fetch(url))
      .then(response => response.json())
      .then(data => {
        results.push(data);
        return results;  // Pasa los resultados acumulados
      });
  }, Promise.resolve());
}

sequentialFetch([
  'https://api.example.com/resource1',
  'https://api.example.com/resource2',
  'https://api.example.com/resource3'
])
.then(allResults => console.log(allResults));

Bifurcación y reunificación

Podemos bifurcar un flujo de promesas y luego reunificarlo:

function getUserWithDetails(userId) {
  return fetch(`/users/${userId}`)
    .then(response => response.json())
    .then(user => {
      // Bifurcación: dos promesas independientes
      const detailsPromise = fetch(`/users/${userId}/details`)
        .then(response => response.json());
        
      const ordersPromise = fetch(`/users/${userId}/orders`)
        .then(response => response.json());
      
      // Reunificación: espera a que ambas promesas se resuelvan
      return Promise.all([user, detailsPromise, ordersPromise]);
    })
    .then(([user, details, orders]) => {
      // Combina los resultados
      return {
        ...user,
        details,
        orders
      };
    });
}

Manejo de errores específicos

Podemos implementar un manejo de errores más granular capturando y procesando errores específicos:

fetchData()
  .then(data => processData(data))
  .catch(error => {
    if (error.name === 'NetworkError') {
      console.log('Network error, retrying...');
      return fetchData();  // Reintentar la operación
    }
    
    if (error.name === 'ValidationError') {
      console.log('Data validation failed');
      return getDefaultData();  // Usar datos predeterminados
    }
    
    // Para otros tipos de errores, propagar
    throw error;
  })
  .then(finalData => {
    // Procesar datos finales
  })
  .catch(error => {
    // Manejador de último recurso
    console.error('Unhandled error:', error);
  });

Encadenamiento condicional

Podemos crear flujos condicionales dentro de cadenas de promesas:

authenticate()
  .then(user => {
    if (user.isAdmin) {
      return fetchAdminData();
    } else {
      return fetchUserData(user.id);
    }
  })
  .then(data => {
    // Procesar los datos obtenidos
    displayData(data);
  });

El encadenamiento y composición de promesas nos permite escribir código asíncrono que fluye de manera natural, casi como si fuera síncrono, manteniendo la legibilidad y facilitando el manejo de errores en aplicaciones complejas.

Operaciones con múltiples promesas: Promise.all, Promise.race y Promise.allSettled

Cuando trabajamos con aplicaciones modernas, a menudo necesitamos gestionar múltiples operaciones asíncronas simultáneamente. JavaScript proporciona métodos estáticos en la clase Promise que nos permiten coordinar y componer varias promesas de manera eficiente.

Promise.all()

El método Promise.all() toma un iterable de promesas (generalmente un array) y devuelve una nueva promesa que se resuelve cuando todas las promesas del iterable se han resuelto, o se rechaza si alguna de ellas falla.

const fetchUserData = fetch('/api/user').then(res => res.json());
const fetchUserPosts = fetch('/api/posts').then(res => res.json());
const fetchUserFollowers = fetch('/api/followers').then(res => res.json());

Promise.all([fetchUserData, fetchUserPosts, fetchUserFollowers])
  .then(([userData, posts, followers]) => {
    // Los tres resultados están disponibles aquí
    console.log(`${userData.name} tiene ${posts.length} publicaciones y ${followers.length} seguidores`);
  })
  .catch(error => {
    // Si cualquiera de las promesas falla, se ejecuta este catch
    console.error('Error al cargar los datos:', error);
  });

Características importantes de Promise.all():

  • Orden preservado: Los resultados se devuelven en el mismo orden que las promesas originales, independientemente del orden en que se resuelvan.
  • Fallo rápido: Si cualquier promesa es rechazada, Promise.all() se rechaza inmediatamente con ese error, sin esperar a que se completen las demás promesas.
  • Array vacío: Si se pasa un array vacío, Promise.all() se resuelve inmediatamente con un array vacío.

Caso de uso: Carga paralela de recursos

function loadPageResources() {
  const resourceUrls = [
    '/api/header-data',
    '/api/main-content',
    '/api/user-preferences',
    '/api/sidebar-widgets'
  ];
  
  const resourcePromises = resourceUrls.map(url => 
    fetch(url)
      .then(response => {
        if (!response.ok) {
          throw new Error(`Failed to load ${url}: ${response.status}`);
        }
        return response.json();
      })
  );
  
  return Promise.all(resourcePromises);
}

loadPageResources()
  .then(resources => {
    renderPage(resources);
  })
  .catch(error => {
    showErrorPage(error);
  });

Promise.race()

El método Promise.race() también acepta un iterable de promesas, pero devuelve una promesa que se resuelve o rechaza tan pronto como una de las promesas del iterable se resuelve o rechaza, con el valor o razón de esa promesa.

const timeoutPromise = new Promise((_, reject) => {
  setTimeout(() => reject(new Error('Timeout')), 5000);
});

const dataPromise = fetch('/api/large-data').then(res => res.json());

Promise.race([dataPromise, timeoutPromise])
  .then(data => {
    console.log('Datos recibidos a tiempo:', data);
  })
  .catch(error => {
    console.error('No se pudo completar la operación:', error);
  });

Características importantes de Promise.race():

  • Primera en completarse: Solo importa la primera promesa que se resuelva o rechace.
  • Comportamiento de carrera: Como su nombre indica, las promesas "compiten" entre sí.
  • Array vacío: Si se pasa un array vacío, la promesa resultante nunca se resolverá.

Caso de uso: Implementación de timeout

function fetchWithTimeout(url, timeout = 5000) {
  const fetchPromise = fetch(url).then(res => res.json());
  
  const timeoutPromise = new Promise((_, reject) => {
    setTimeout(() => {
      reject(new Error(`Request timed out after ${timeout}ms`));
    }, timeout);
  });
  
  return Promise.race([fetchPromise, timeoutPromise]);
}

fetchWithTimeout('/api/data', 3000)
  .then(data => {
    displayData(data);
  })
  .catch(error => {
    if (error.message.includes('timed out')) {
      showTimeoutMessage();
    } else {
      showErrorMessage(error);
    }
  });

Promise.allSettled()

Introducido en ES2020, Promise.allSettled() toma un iterable de promesas y devuelve una promesa que se resuelve cuando todas las promesas han sido establecidas (ya sea resueltas o rechazadas). A diferencia de Promise.all(), nunca se rechaza.

const promises = [
  fetch('/api/endpoint1').then(res => res.json()),
  fetch('/api/endpoint2').then(res => res.json()),
  fetch('/api/nonexistent').then(res => res.json())
];

Promise.allSettled(promises)
  .then(results => {
    results.forEach((result, index) => {
      if (result.status === 'fulfilled') {
        console.log(`Promesa ${index} completada:`, result.value);
      } else {
        console.log(`Promesa ${index} fallida:`, result.reason);
      }
    });
  });

Cada resultado en el array tiene esta estructura:

  • Para promesas cumplidas: { status: 'fulfilled', value: resultado }
  • Para promesas rechazadas: { status: 'rejected', reason: error }

Características importantes de Promise.allSettled():

  • Siempre se resuelve: Nunca se rechaza, independientemente de si alguna promesa individual falla.
  • Información completa: Proporciona el estado y resultado/razón de cada promesa.
  • Orden preservado: Los resultados mantienen el mismo orden que las promesas originales.

Caso de uso: Operaciones parciales

function syncMultipleAccounts(accountIds) {
  const syncPromises = accountIds.map(id => 
    syncAccount(id)
      .then(result => ({ status: 'fulfilled', id, result }))
      .catch(error => ({ status: 'rejected', id, error }))
  );
  
  return Promise.allSettled(syncPromises)
    .then(results => {
      const successful = results.filter(r => r.status === 'fulfilled');
      const failed = results.filter(r => r.status === 'rejected');
      
      return {
        totalAccounts: accountIds.length,
        successfulSyncs: successful.length,
        failedSyncs: failed.length,
        failedAccountIds: failed.map(f => f.id)
      };
    });
}

syncMultipleAccounts([1001, 1002, 1003, 1004])
  .then(summary => {
    console.log(`Sincronización completada: ${summary.successfulSyncs}/${summary.totalAccounts} cuentas sincronizadas`);
    
    if (summary.failedSyncs > 0) {
      console.warn(`No se pudieron sincronizar ${summary.failedSyncs} cuentas:`, summary.failedAccountIds);
    }
  });

Promise.any()

Añadido en ES2021, Promise.any() toma un iterable de promesas y devuelve una promesa que se resuelve tan pronto como una de las promesas del iterable se resuelve. Si todas las promesas son rechazadas, devuelve un AggregateError que contiene todos los errores.

const mirrors = [
  'https://mirror1.example.com/file',
  'https://mirror2.example.com/file',
  'https://mirror3.example.com/file'
];

const downloadPromises = mirrors.map(url => fetch(url));

Promise.any(downloadPromises)
  .then(firstResponse => {
    console.log('Descarga iniciada desde el primer mirror disponible');
    return firstResponse.blob();
  })
  .then(blob => {
    saveFile(blob);
  })
  .catch(error => {
    // Se ejecuta solo si todos los mirrors fallan
    console.error('Todos los mirrors fallaron:', error);
  });

Características importantes de Promise.any():

  • Primera en cumplirse: Devuelve la primera promesa que se resuelve correctamente.
  • Ignora rechazos: Los rechazos se ignoran hasta que todas las promesas sean rechazadas.
  • AggregateError: Si todas fallan, devuelve un error especial que contiene todos los errores individuales.

Caso de uso: Redundancia y failover

function fetchWithFailover(urls) {
  const fetchPromises = urls.map(url => 
    fetch(url)
      .then(response => {
        if (!response.ok) {
          throw new Error(`HTTP error ${response.status}`);
        }
        return response.json();
      })
  );
  
  return Promise.any(fetchPromises);
}

fetchWithFailover([
  'https://api-primary.example.com/data',
  'https://api-backup1.example.com/data',
  'https://api-backup2.example.com/data'
])
  .then(data => {
    processData(data);
  })
  .catch(error => {
    console.error('Todos los endpoints fallaron:', error);
    showFallbackUI();
  });

Comparación de métodos para múltiples promesas

Método Resuelve cuando Rechaza cuando Caso de uso típico
Promise.all() Todas las promesas se resuelven Cualquier promesa se rechaza Operaciones interdependientes
Promise.race() La primera promesa se resuelve La primera promesa se rechaza Timeouts, cancelaciones
Promise.allSettled() Todas las promesas se establecen Nunca se rechaza Operaciones independientes
Promise.any() Cualquier promesa se resuelve Todas las promesas se rechazan Redundancia, failover

Estos métodos para trabajar con múltiples promesas nos permiten implementar patrones complejos de concurrencia y coordinación en aplicaciones JavaScript, manteniendo un código limpio y fácil de mantener.

Aprende JavaScript online

Otros ejercicios de programación de JavaScript

Evalúa tus conocimientos de esta lección Promises con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Clases y objetos

JavaScript
Código

Uso de operadores

JavaScript
Puzzle

Uso de operadores

JavaScript
Test

Estructuras de control

JavaScript
Test

Proyecto Manipulación DOM

JavaScript
Proyecto

Excepciones

JavaScript
Test

Transformación con map()

JavaScript
Código

Arrays y Métodos

JavaScript
Código

Reto Métodos de Strings

JavaScript
Código

Transformación con map()

JavaScript
Puzzle

Funciones flecha

JavaScript
Test

Async / Await

JavaScript
Código

Selección de elementos DOM

JavaScript
Puzzle

API Fetch

JavaScript
Código

Encapsulación

JavaScript
Test

Mapas con Map

JavaScript
Código

Creación y uso de variables

JavaScript
Puzzle

Polimorfismo

JavaScript
Puzzle

Reto Funciones flecha

JavaScript
Código

Tipos de datos

JavaScript
Puzzle

Reto Operadores avanzados

JavaScript
Código

Promises

JavaScript
Código

Reto Estructuras de control

JavaScript
Código

Estructuras de control

JavaScript
Puzzle

Pruebas unitarias

JavaScript
Proyecto

Inmutabilidad y programación funcional pura

JavaScript
Código

Funciones flecha

JavaScript
Puzzle

Polimorfismo

JavaScript
Test

Reto Polimorfismo

JavaScript
Código

Array

JavaScript
Código

Transformación con map()

JavaScript
Test

Reto Variables

JavaScript
Código

Gestor de tareas con JavaScript

JavaScript
Proyecto

Proyecto Modificación de elementos DOM

JavaScript
Proyecto

Manipulación DOM

JavaScript
Test

Funciones

JavaScript
Test

Conjuntos con Set

JavaScript
Código

Reto Prototipos y cadena de prototipos

JavaScript
Código

Reto Encapsulación

JavaScript
Código

Funciones flecha

JavaScript
Código

Async / Await

JavaScript
Código

Reto Excepciones

JavaScript
Código

Reto Filtrado con filter() y find()

JavaScript
Código

Creación y uso de variables

JavaScript
Test

Excepciones

JavaScript
Puzzle

Promises

JavaScript
Código

Funciones cierre (closure)

JavaScript
Test

Reto Herencia

JavaScript
Código

Herencia

JavaScript
Puzzle

Proyecto Eventos del DOM

JavaScript
Proyecto

Herencia

JavaScript
Test

Selección de elementos DOM

JavaScript
Test

Modificación de elementos DOM

JavaScript
Test

Reto Clases y objetos

JavaScript
Código

Filtrado con filter() y find()

JavaScript
Test

Funciones cierre (closure)

JavaScript
Puzzle

Reto Destructuring de objetos y arrays

JavaScript
Código

Callbacks

JavaScript
Código

Funciones

JavaScript
Puzzle

Mapas con Map

JavaScript
Test

Reducción con reduce()

JavaScript
Test

Callbacks

JavaScript
Puzzle

Manipulación DOM

JavaScript
Puzzle

Introducción al DOM

JavaScript
Proyecto

Reto Funciones

JavaScript
Código

Reto Funciones cierre (closure)

JavaScript
Código

Promises

JavaScript
Test

Reto Reducción con reduce()

JavaScript
Código

Async / Await

JavaScript
Test

Reto Estructuras de control

JavaScript
Código

Eventos del DOM

JavaScript
Puzzle

Introducción a JavaScript

JavaScript
Puzzle

Async / Await

JavaScript
Puzzle

Promises

JavaScript
Puzzle

Selección de elementos DOM

JavaScript
Proyecto

Filtrado con filter() y find()

JavaScript
Código

Callbacks

JavaScript
Test

Creación de clases y objetos Restaurante

JavaScript
Código

Reducción con reduce()

JavaScript
Código

Filtrado con filter() y find()

JavaScript
Puzzle

Reducción con reduce()

JavaScript
Puzzle

Conjuntos con Set

JavaScript
Puzzle

Herencia de clases

JavaScript
Código

Eventos del DOM

JavaScript
Test

Clases y objetos

JavaScript
Puzzle

Modificación de elementos DOM

JavaScript
Puzzle

Mapas con Map

JavaScript
Puzzle

Proyecto carrito compra agoodshop

JavaScript
Proyecto

Introducción a JavaScript

JavaScript
Test

Reto Mapas con Map

JavaScript
Código

Funciones

JavaScript
Código

Proyecto administrador de contactos

JavaScript
Proyecto

Reto Expresiones regulares

JavaScript
Código

Tipos de datos

JavaScript
Test

Clases y objetos

JavaScript
Test

Array

JavaScript
Test

Conjuntos con Set

JavaScript
Test

Array

JavaScript
Puzzle

Encapsulación

JavaScript
Puzzle

Todas las lecciones de JavaScript

Accede a todas las lecciones de JavaScript y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Introducción A Javascript

JavaScript

Introducción Y Entorno

Tipos De Datos

JavaScript

Sintaxis

Variables

JavaScript

Sintaxis

Operadores

JavaScript

Sintaxis

Estructuras De Control

JavaScript

Sintaxis

Funciones

JavaScript

Sintaxis

Funciones Cierre (Closure)

JavaScript

Sintaxis

Métodos De Strings

JavaScript

Sintaxis

Funciones Cierre (Closure)

JavaScript

Sintaxis

Operadores Avanzados

JavaScript

Sintaxis

Funciones

JavaScript

Sintaxis

Expresiones Regulares

JavaScript

Sintaxis

Estructuras De Control

JavaScript

Sintaxis

Arrays Y Métodos

JavaScript

Estructuras De Datos

Conjuntos Con Set

JavaScript

Estructuras De Datos

Mapas Con Map

JavaScript

Estructuras De Datos

Conjuntos Con Set

JavaScript

Estructuras De Datos

Funciones Flecha

JavaScript

Programación Funcional

Filtrado Con Filter() Y Find()

JavaScript

Programación Funcional

Transformación Con Map()

JavaScript

Programación Funcional

Reducción Con Reduce()

JavaScript

Programación Funcional

Funciones Flecha

JavaScript

Programación Funcional

Transformación Con Map()

JavaScript

Programación Funcional

Inmutabilidad Y Programación Funcional Pura

JavaScript

Programación Funcional

Clases Y Objetos

JavaScript

Programación Orientada A Objetos

Excepciones

JavaScript

Programación Orientada A Objetos

Encapsulación

JavaScript

Programación Orientada A Objetos

Herencia

JavaScript

Programación Orientada A Objetos

Polimorfismo

JavaScript

Programación Orientada A Objetos

This Y Contexto

JavaScript

Programación Orientada A Objetos

Patrón De Módulos Y Namespace

JavaScript

Programación Orientada A Objetos

Prototipos Y Cadena De Prototipos

JavaScript

Programación Orientada A Objetos

Destructuring De Objetos Y Arrays

JavaScript

Programación Orientada A Objetos

Manipulación Dom

JavaScript

Dom

Selección De Elementos Dom

JavaScript

Dom

Modificación De Elementos Dom

JavaScript

Dom

Eventos Del Dom

JavaScript

Dom

Localstorage Y Sessionstorage

JavaScript

Dom

Bom (Browser Object Model)

JavaScript

Dom

Callbacks

JavaScript

Programación Asíncrona

Promises

JavaScript

Programación Asíncrona

Async / Await

JavaScript

Programación Asíncrona

Promises

JavaScript

Programación Asíncrona

Api Fetch

JavaScript

Programación Asíncrona

Async / Await

JavaScript

Programación Asíncrona

Naturaleza De Js Y Event Loop

JavaScript

Programación Asíncrona

Callbacks

JavaScript

Programación Asíncrona

Websockets

JavaScript

Programación Asíncrona

Módulos En Es6

JavaScript

Construcción

Configuración De Bundlers Como Vite

JavaScript

Construcción

Eslint Y Calidad De Código

JavaScript

Construcción

Npm Y Dependencias

JavaScript

Construcción

Introducción A Pruebas En Js

JavaScript

Testing

Pruebas Unitarias

JavaScript

Testing

Accede GRATIS a JavaScript y certifícate

En esta lección

Objetivos de aprendizaje de esta lección

  1. Entender el concepto de promesas en JavaScript y su utilidad para operaciones asincrónicas.
  2. Aprender a crear promesas utilizando el constructor Promise.
  3. Conocer los métodos then, catch y finally para consumir y manejar el resultado de las promesas.
  4. Familiarizarse con el encadenamiento de promesas para realizar operaciones asincrónicas en secuencia.
  5. Aprender a manejar múltiples promesas en paralelo utilizando Promise.all.
  6. Entender cómo las promesas mejoran la legibilidad y estructura del código en situaciones con operaciones asíncronas.