Explicación de las promesas de JavaScript: luego, captura, Promise.all y errores comunes

  1. Inicio
  2. Blog
  3. Desarrollo de software

Desarrollo de software

Explicación de las promesas de JavaScript: luego, capture, Promise.all y errores comunes

Las promesas son la forma en que JavaScript maneja el trabajo que finaliza más tarde, y async/await se construye sobre ellas. Aprenda cómo se comportan realmente, con resultados reales de cada ejemplo, y evite los errores que se tragan sus errores.

10 min de lectura
Explicación de las promesas de JavaScript: luego, captura, Promise.all y errores comunes

Puntos clave

  • Una promesa es un objeto que representa un resultado que estará disponible más adelante.
  • Está pendiente hasta que se cumpla o se rechace, y una vez resuelto nunca cambia.
  • Cada then devuelve una nueva promesa, que es lo que hace posible el encadenamiento.
  • Utilice Promise.all cuando se requieran todos los resultados y Promise.allSettled cuando desee todos los resultados.

Las solicitudes de red, las lecturas de archivos y los temporizadores finalizan más tarde, pero JavaScript no puede simplemente detenerse y esperar, o la página se congelaría. Las promesas de JavaScript le brindan una manera ordenada de decir “cuando esto termine, haga aquello, y si falla, haga esto en su lugar”.

Incluso si escribe principalmente async y await, está utilizando promesas debajo, por lo que comprenderlas facilita mucho la depuración. Ejecutamos estos ejemplos en Node.js 24 y el resultado que se muestra proviene de esa ejecución. Se comportan de la misma manera en los navegadores modernos.

¿Qué es una promesa?

Una promesa es un marcador de posición para un valor futuro. Piensa en el timbre que te da un restaurante cuando haces un pedido. Aún no tienes tu comida, pero sostienes algo que te dirá cuando está lista, o que hay un problema, y ​​mientras tanto eres libre de hacer otras cosas.

En el código, una función asincrónica devuelve una promesa inmediatamente y usted adjunta lo que debería suceder a continuación:

fetch("/api/user")
  .then((response) => response.json())
  .then((user) => console.log(user.name))
  .catch((error) => console.log("Failed:", error.message));

Los tres estados de promesa

Estado Significado que corre
Pendiente El trabajo no ha terminado Nada todavía
Cumplido Terminó con un valor then manejadores
Rechazado Falló con una razón catch manejadores

Una promesa que se cumple o se rechaza se llama cumplida. Una promesa sólo puede cumplirse una vez. Después de eso, su estado y valor se fijan y las llamadas posteriores a resolve o reject se ignoran.

Crea una promesa

Por lo general, consume promesas de API como fetch, pero crear una muestra cómo funcionan. El constructor recibe dos funciones, resolve y reject:

function fetchUser(id) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (id > 0) {
        resolve({ id, name: "Asha" });
      } else {
        reject(new Error("Invalid id"));
      }
    }, 100);
  });
}

console.log(fetchUser(1));

// Promise { <pending> }

Registrar la promesa de inmediato muestra que aún está pendiente porque el temporizador no se ha activado. El valor solo se puede alcanzar a través de un controlador o await. Rechace siempre con un objeto Error en lugar de una cadena, ya que un Error lleva un seguimiento de la pila que ayuda con la depuración.

luego, atrapar y finalmente

Estos tres métodos adjuntan controladores a una promesa:

fetchUser(1).then((user) => console.log(user.name));
// Asha

fetchUser(-1)
  .then((user) => console.log("never runs", user))
  .catch((error) => console.log("caught:", error.message))
  .finally(() => console.log("finally"));

// caught: Invalid id
// finally

then se ejecuta en caso de éxito, catch se ejecuta en caso de error y finally se ejecuta en cualquier sentido. Eso hace que finally sea el lugar adecuado para la limpieza, como ocultar un control giratorio de carga. No recibe argumentos, porque no debería importarle el resultado.

Encadenando promesas

La idea clave es que then siempre devuelve una nueva promesa. Lo que sea que devuelva su controlador se convierte en el valor de esa nueva promesa:

Promise.resolve(2)
  .then((n) => n * 10)
  .then((n) => n + 1)
  .then((n) => console.log("chain:", n));

// chain: 21

Si un controlador devuelve otra promesa, la cadena espera a que se establezca antes de continuar. Esto es lo que convierte las devoluciones de llamadas anidadas en una secuencia plana de pasos:

getUser(id)
  .then((user) => getOrders(user.id))
  .then((orders) => getInvoice(orders[0].id))
  .then((invoice) => console.log(invoice.total))
  .catch(handleError);

Cómo viajan los errores a través de una cadena

Una promesa rechazada se salta cada then hasta llegar a un catch. Lanzar dentro de un guía también cuenta como un rechazo. Y un catch que regresa normalmente vuelve a encarrilar la cadena:

Promise.resolve("start")
  .then(() => {
    throw new Error("step 2 failed");
  })
  .then(() => console.log("skipped"))
  .catch((error) => {
    console.log("caught:", error.message);
    return "recovered";
  })
  .then((value) => console.log("continues:", value));

// caught: step 2 failed
// continues: recovered

Piense en esto como la versión asincrónica de try y catch. Un catch al final suele cubrir toda la cadena. Si solo desea registrar un error y aún así falla, tírelo nuevamente desde el interior del catch.

Consejo: fetch rechaza solo por fallas de red. Una respuesta 404 o 500 aún cumple, así que verifique response.ok usted mismo. Nuestra hoja de referencia de códigos de estado HTTP explica lo que significa cada código.

Promise.all, allSettled, raza y cualquiera

Estos métodos estáticos coordinan varias promesas a la vez. Todos ellos toman una matriz y devuelven una promesa.

Método Cumple cuando Rechaza cuando Úselo para
Promise.all todos cumplen Cualquiera rechaza Todos los resultados son requeridos
Promise.allSettled Todo se resuelve nunca Quieres todos los resultados
Promise.race El primero en conformarse cumple El primero en resolver los rechazos. Tiempos de espera
Promise.any El primero cumple todos rechazan La primera fuente exitosa

Para probarlos, utilizamos dos pequeños ayudantes, uno que tiene éxito después de un retraso y otro que falla después de un retraso:

const wait = (ms, value) =>
  new Promise((resolve) => setTimeout(() => resolve(value), ms));
const fail = (ms, message) =>
  new Promise((_, reject) => setTimeout(() => reject(new Error(message)), ms));

Promise.all

await Promise.all([wait(300, "a"), wait(100, "b"), wait(200, "c")]);

// [ 'a', 'b', 'c' ]   took about 300 ms

Dos detalles a destacar. Los resultados mantienen el orden de entrada, aunque b termine primero. Y el tiempo total fue de unos 300 ms, el tiempo de la tarea más lenta y no la suma de los 600 ms, porque ya estaban ejecutándose las tres a la vez. Si alguno de ellos rechaza, todo el conjunto rechaza inmediatamente:

await Promise.all([wait(100, "a"), fail(50, "b failed")]);

// rejected: b failed

Promise.allSettled

Este espera todo e informa cada resultado, para que un fallo no pierda el resto. Se adapta a un panel donde cada widget se carga de forma independiente:

const results = await Promise.allSettled([wait(50, "a"), fail(50, "b failed")]);
results.map((r) => r.status);

// [ 'fulfilled', 'rejected' ]

Promesa.race y Promesa.cualquiera

await Promise.race([wait(300, "slow"), wait(100, "fast")]);   // fast
await Promise.any([fail(50, "x"), wait(100, "ok")]);          // ok

La diferencia es que race toma el primero en resolverse, incluso si falló, mientras que any ignora los fracasos siempre que algo tenga éxito. Un uso clásico de race es agregar un tiempo de espera a una solicitud lenta, aunque la tarea más lenta continúa ejecutándose en segundo plano a menos que la cancele.

Promesas y async/await

async y await son una forma más legible de trabajar con las mismas promesas. Una función async siempre devuelve una promesa y await pausa esa función hasta que se cumpla una promesa:

async function showInvoice(id) {
  try {
    const user = await getUser(id);
    const orders = await getOrders(user.id);
    console.log(orders.length);
  } catch (error) {
    console.log("Failed:", error.message);
  }
}

Los rechazos se convierten en errores, por lo que try y catch ordinarios funcionan. Aún necesitas Promise.all para el trabajo paralelo, porque esperar una llamada tras otra las ejecuta en secuencia. Nuestra guía de JavaScript async/await profundiza en esto.

Promesas y el bucle de eventos.

Los manejadores de promesas nunca son llamados inmediatamente, incluso cuando la promesa ya se ha cumplido. Se ejecutan después de que finaliza el código actual y antes de cualquier temporizador. Aquí está la prueba:

setTimeout(() => console.log("timeout"), 0);
Promise.resolve().then(() => console.log("microtask"));
console.log("sync");

// sync
// microtask
// timeout

El código sincrónico se ejecuta primero. Luego viene la cola de microtareas, que contiene controladores de promesas. Sólo entonces el bucle de eventos selecciona la siguiente tarea, como un temporizador. Esta es una pregunta de entrevista popular y explica por qué un setTimeout de cero no es realmente inmediato.

Promesas versus devoluciones de llamada

Preocupación Devoluciones de llamada Promesas
Secuenciación Anidado, más profundo en cada paso. una cadena plana
Errores Comprobado en todos los niveles. Uno catch puede cubrir la cadena.
Trabajo paralelo Contadores manuales Promise.all
¿Llamado dos veces por error? Posible No puedo llegar a un acuerdo dos veces

Errores comunes

  • Olvidarse de regresar al interior de then. Sin un return, el siguiente paso recibe undefined y no espera tu promesa interior.
  • No catch en absoluto. Esto provoca un rechazo no controlado y, en Node.js, detiene el proceso de forma predeterminada.
  • Anidar en lugar de encadenar. Poner then dentro de then recrea el infierno de las devoluciones de llamadas. Devuelve la promesa y continúa la cadena.
  • Envolviendo una promesa en new Promise. Si una función ya devuelve una promesa, simplemente úsela.
  • Usando forEach con devoluciones de llamada asíncronas. No espera. Utilice for...of o Promise.all con map, como se muestra en nuestra guía de métodos de matriz de JavaScript.
  • Pensar que una promesa se puede cancelar. No puede por sí sola. Para solicitudes, utilice AbortController.

Conclusión

Las promesas se reducen a unas pocas reglas: una promesa se cumple una vez, then devuelve una nueva promesa y los errores viajan a lo largo de la cadena hasta que algo los detecta. Una vez que esas reglas se sientan naturales, async y await dejan de ser mágicas. Para practicar, reescriba una función basada en devolución de llamada usando promesas, luego busque dos puntos finales con Promise.all y maneje una falla adecuadamente.

Preguntas frecuentes

¿Qué es una promesa en JavaScript?

Una promesa es un objeto que representa el resultado final de un trabajo asincrónico. Comienza como pendiente, luego cumple con un valor o rechaza con un motivo.

¿Cuál es la diferencia entre entonces y atrapar?

luego se ejecuta cuando se cumple una promesa y se ejecuta catch cuando se rechaza. catch es efectivamente entonces con solo un controlador de rechazo, y también puede detectar errores lanzados en pasos anteriores.

¿Cuál es la diferencia entre Promise.all y Promise.allSettled?

Promise.all se rechaza tan pronto como se rechaza una promesa. Promise.allSettled siempre espera a todos e informa el estado y el valor o motivo de cada uno.

¿Debo usar promesas o async/await?

Trabajan juntos, ya que la espera se basa en promesas. La mayor parte del código se lee mejor con async/await, mientras que Promise.all y métodos similares siguen siendo útiles para el trabajo paralelo.

¿Las promesas se ejecutan en paralelo?

JavaScript ejecuta un fragmento de código a la vez en un hilo, pero funciona como si las solicitudes de red se realizaran en segundo plano. Varios de estos pueden estar en progreso a la vez.

sigue aprendiendo

Trabajar con Stack Quora

¿Necesitas ayuda con pruebas, WordPress o SEO?

Ayudamos a los equipos a enviar mejor software y hacer crecer sus sitios. Cuéntenos en qué está trabajando y le sugeriremos un siguiente paso claro.

Sigue leyendo

Más guías sobre testing, IA y desarrollo moderno

¿Te gustó este artículo? Elige un tema y salta directo a nuestros tutoriales más recientes.

Inteligencia artificial

Explicación de las alucinaciones de la IA: por qué los modelos de lenguaje inventan cosas y cómo reducirlas

Se explicaron las alucinaciones de la IA: qué son, por qué los modelos de lenguaje las producen, tipos comunes, cómo reducirlas con conexión a tierr…

Leer artículo →
DevOps

Explicación de las variables de entorno: archivos .env, secretos y configuración bien hechos

Variables de entorno explicadas con ejemplos de Python que ejecutamos: leerlas y configurarlas, por qué cada valor es una cadena, archivos .env, her…

Leer artículo →
Desarrollo de software

Explicación de la limitación de velocidad de API: algoritmos, encabezados y manejo de errores 429

La limitación de la tasa de API se explica con una simulación que ejecutamos: depósito de tokens, ventana fija, ventana deslizante, 429 respuestas, …

Leer artículo →
Automatización de pruebas

Burlarse en Python: unittest.mock, patch y los errores que hacen que las pruebas mientan

Burlarse en Python con unittest.mock, probado: Mock y return_value, side_effect, parches donde se usa un nombre, especificación y autospec, fechas d…

Leer artículo →
Pruebas de software

Explicación de la cobertura del código: cobertura de línea versus sucursal y lo que realmente significa 100%

Cobertura del código explicada con una ejecución real de cobertura.py: cobertura de línea, rama y condición, lectura de un informe, por qué una cobe…

Leer artículo →
Bases de datos y SQL

DELETE vs TRUNCATE vs DROP en SQL: diferencias, reversión y cuándo usar cada uno

DELETE vs TRUNCATE vs DROP explicado con SQL probado: qué elimina cada uno, reversión, activadores, restablecimiento de identidad, velocidad y en qu…

Leer artículo →
Bases de datos y SQL

Vistas SQL explicadas: cree, use y evite los errores, con ejemplos

Vistas SQL explicadas con consultas que ejecutamos: creación de una vista, resultados en vivo, ocultación de columnas, rendimiento, vistas actualiza…

Leer artículo →
Desarrollo de software

Interfaz TypeScript versus tipo: diferencias reales, probadas con el compilador

Interfaz TypeScript versus tipo, verificado con el compilador real: qué pueden hacer ambos, qué puede hacer solo uno, fusión de declaraciones, exten…

Leer artículo →
Desarrollo de software

Python *args y **kwargs explicados: funciones flexibles con ejemplos claros

Python *args y **kwargs explicados con el código que ejecutamos: empaquetado y desempaquetado, orden de parámetros, argumentos solo de palabras clav…

Leer artículo →
Desarrollo de software

Funciones Lambda de Python: sintaxis, usos reales y cuándo no utilizarlas

Funciones lambda de Python explicadas con el código que ejecutamos: sintaxis, clasificación con clave, mapa y filtro, cierres, trampa de enlace tard…

Leer artículo →
Inteligencia artificial

¿Qué son los agentes de IA? Cómo funcionan, con un bucle de agente simple que puedes ejecutar

¿Qué son los agentes de IA? Una guía sencilla sobre el bucle del agente, las herramientas, la memoria y las barreras de seguridad, con un pequeño bu…

Leer artículo →
DevOps

Monitoreo versus observabilidad: la verdadera diferencia, con registros, métricas y seguimientos

Explicación del monitoreo versus observabilidad: fallas conocidas y desconocidas, registros, métricas y seguimientos, un recorrido por incidentes de…

Leer artículo →
DevOps

Docker Volumes versus Bind Mounts: persistir los datos del contenedor de la manera correcta

Se explican los volúmenes de Docker frente a los montajes de enlace: por qué desaparecen los datos del contenedor, volúmenes con nombre, montajes de…

Leer artículo →
Automatización de pruebas

TDD vs BDD: diferencias clave, una función creada en ambos sentidos y cuándo usar cada una

TDD vs BDD explicado con una característica de descuento construida en ambos sentidos: refactor rojo-verde con el código que ejecutamos, escenarios …

Leer artículo →
Pruebas de software

Pruebas de Aceptación de Usuario (UAT): Proceso, Lista de Verificación y Ejemplos Reales

Explicación de las pruebas de aceptación del usuario: quién las ejecuta, en qué se diferencia del control de calidad, un proceso de siete pasos, una…

Leer artículo →
Bases de datos y SQL

Valores NULL de SQL explicados: IS NULL, COALESCE, NULLIF y las trampas que se deben evitar

Los valores NULL de SQL se explican con las consultas que ejecutamos: lógica de tres valores, IS NULL, COALESCE, NULLIF, cómo los agregados, las uni…

Leer artículo →
Bases de datos y SQL

Declaración SQL CASE WHEN: sintaxis, ejemplos reales y errores comunes

CASO SQL CUANDO se explicó con las consultas que ejecutamos: formularios simples y buscados, orden de condiciones, pivotes con SUMA, trucos COUNT, c…

Leer artículo →
Desarrollo de software

¿Qué es JWT? Tokens web JSON explicados con un ejemplo práctico

¿Qué es JWT? JSON Web Tokens explicó: las tres partes, un token creado y manipulado en el código que ejecutamos, JWT vs sesiones, almacenamiento, to…

Leer artículo →
Desarrollo de software

Explicación del bucle de eventos de JavaScript: pila de llamadas, microtareas y temporizadores con ejemplos

El bucle de eventos de JavaScript explicado con el código que ejecutamos: pila de llamadas, colas de tareas y microtareas, por qué setTimeout 0 no e…

Leer artículo →
Desarrollo de software

Explicación de los generadores y el rendimiento de Python: ahorre memoria con ejemplos reales

Los generadores de Python y el rendimiento se explican con el código que ejecutamos: cómo se pausan y reanudan, midieron el ahorro de memoria, canal…

Leer artículo →
Inteligencia artificial

¿Qué son las incrustaciones? Los vectores y la similitud del coseno se explican de forma sencilla

¿Qué son las incrustaciones? Una guía en lenguaje sencillo sobre vectores, similitud de cosenos y búsqueda semántica, con un pequeño ejemplo que eje…

Leer artículo →
DevOps

Implementación azul-verde versus implementación canaria: diferencias, compensaciones y cómo elegir

Explicación de la implementación azul-verde versus canaria: cómo funciona cada uno, costo, riesgo y reversión, agrupación estable de usuarios que pr…

Leer artículo →
Automatización de pruebas

Pruebas inestables: qué las causa y cómo solucionarlas para siempre

Pruebas inestables explicadas con demostraciones que realizamos: las causas principales, cómo confirmar y diagnosticar una, correcciones adecuadas p…

Leer artículo →
Pruebas de software

Pruebas de carga frente a pruebas de estrés: diferencias, métricas y ejemplos de k6

Explicación de las pruebas de carga frente a las pruebas de estrés: qué prueba cada una, pruebas de picos y de absorción, las métricas que importan,…

Leer artículo →
Pruebas de software

Caso de prueba frente a escenario de prueba: diferencias clave, ejemplos y cuándo utilizar cada uno

Caso de prueba versus escenario de prueba explicado: definiciones claras, una tabla en paralelo, una función de restablecimiento de contraseña tomad…

Leer artículo →
Bases de datos y SQL

Optimización de consultas SQL: lea planes de ejecución y corrija consultas lentas, con tiempos

Optimización de consultas SQL probada en un millón de filas: lea planes de ejecución, agregue los índices correctos, corrija filtros no sargables, u…

Leer artículo →
Bases de datos y SQL

SQL UNION vs UNION ALL: diferencias, ejemplos y rendimiento probado

SQL UNION vs UNION ALL explicado con consultas que ejecutamos: duplicados, las reglas que siguen ambos, un error de datos real, rendimiento medido, …

Leer artículo →
Desarrollo de software

Tutorial de JavaScript Fetch API: GET, POST, manejo de errores y tiempos de espera

Un tutorial de JavaScript Fetch API probado en un servidor local: GET y POST, por qué 404 no arroja, un asistente reutilizable, cadenas de consulta,…

Leer artículo →
Desarrollo de software

Manejo de archivos Python: lectura, escritura, CSV, JSON y pathlib con ejemplos

El manejo de archivos Python se explica con el código que ejecutamos: modos abiertos, lectura de archivos grandes, CSV, JSON, pathlib, archivos bina…

Leer artículo →
Desarrollo de software

Clases y objetos de Python: tutorial de programación orientada a objetos con ejemplos reales

Clases y objetos de Python explicados con el código que ejecutamos: __init__, métodos, atributos de clase versus instancia, herencia, propiedades, m…

Leer artículo →
Inteligencia artificial

¿Qué es un modelo de lenguaje grande? Cómo funcionan los LLM, explicados sin exageraciones

¿Qué es un modelo de lenguaje grande? Los LLM explicados en lenguaje sencillo: tokens, incrustaciones, atención, entrenamiento, ventanas de temperat…

Leer artículo →
DevOps

Comandos de Linux para principiantes: la guía esencial de terminal con ejemplos

Comandos de Linux para principiantes, agrupados por tarea: navegación, archivos, visualización de registros, grep, canalizaciones, permisos, proceso…

Leer artículo →
Automatización de pruebas

Selenium vs Playwright: diferencias clave, comparación de códigos y cuál elegir

Comparación de Selenium vs Playwright: arquitectura, espera, soporte de navegador e idioma, depuración, la misma prueba en ambas herramientas, conse…

Leer artículo →
Pruebas de software

Partición de equivalencia: técnica de diseño de pruebas explicada con ejemplos resueltos

Explicación de la partición de equivalencia: cómo encontrar particiones válidas e inválidas, ejemplos prácticos para edades, contraseñas y cupones, …

Leer artículo →
Pruebas de software

Severidad vs Prioridad en Pruebas de Software: Diferencias, Matriz y Ejemplos Reales

Explicación de gravedad versus prioridad en las pruebas de software: definiciones claras, una matriz de cuatro vías con ejemplos, escalas de niveles…

Leer artículo →
Bases de datos y SQL

Tutorial de subconsultas SQL: tipos, subconsultas correlacionadas y EXISTENCIAS con ejemplos

Un tutorial de subconsultas SQL con consultas que ejecutamos: subconsultas escalares, IN, FROM y SELECT, subconsultas correlacionadas, EXISTS, la tr…

Leer artículo →
Bases de datos y SQL

Transacciones SQL y ACID explicados: COMMIT, ROLLBACK y niveles de aislamiento

Transacciones SQL y ACID explicadas con una transferencia bancaria que ejecutamos: COMMIT, ROLLBACK, puntos de guardado, bloqueos, niveles de aislam…

Leer artículo →
Desarrollo de software

Hoja de trucos de comandos de Git: los comandos que realmente usas, con ejemplos

Una hoja de referencia de comandos de Git agrupada por tarea: configuración, preparación, ramas, controles remotos, almacenamiento, historial y desh…

Leer artículo →
Desarrollo de software

Explicación de las promesas de JavaScript: luego, captura, Promise.all y errores comunes

Las promesas de JavaScript se explican con el código que ejecutamos: estados, luego y cadenas de captura, manejo de errores, Promise.all, allSettled…

Leer artículo →
Desarrollo de software

Tutorial del diccionario Python: métodos, ejemplos y patrones comunes

Un tutorial de diccionario de Python con el código que ejecutamos: crear, leer y actualizar dictados, métodos clave, fusión, comprensión, patrones d…

Leer artículo →
Inteligencia artificial

¿Qué es el RAG? Generación de recuperación aumentada explicada con un ejemplo práctico

¿Qué es RAG? Generación de recuperación aumentada explicada paso a paso: indexación, fragmentación, incrustaciones, recuperación, un pequeño ejemplo…

Leer artículo →
DevOps

Tutorial de Terraform para principiantes: infraestructura como código desde el primer archivo hasta los módulos

Un tutorial de Terraform para principiantes: comience sin una cuenta en la nube, aprenda init, planifique y aplique, luego variables, resultados, es…

Leer artículo →
DevOps

Docker vs Kubernetes: diferencias clave, cómo funcionan juntos y cuál necesita

Docker vs Kubernetes explicó: qué hace cada uno, la misma aplicación se ejecuta con ambos, se comparan Docker Compose y Swarm, los Dockershim cambia…

Leer artículo →
Automatización de pruebas

Tutorial de Pytest para principiantes: accesorios, parametrización y ejemplos reales

Un tutorial de pytest para principiantes con pruebas que ejecutamos en pytest 9.2: afirmaciones, accesorios, parametrización, conftest, marcadores, …

Leer artículo →
Pruebas de software

Ciclo de vida de pruebas de software (STLC): 6 fases, criterios de entrada y salida, ejemplo

Se explicó el ciclo de vida de las pruebas de software: seis fases de STLC con criterios de entrada y salida, entregables, un ejemplo de función de …

Leer artículo →
Desarrollo de software

Git merge vs rebase: diferencias, ejemplos y cuándo usar cada uno

Git merge vs rebase explicado con salida real del log, una tabla comparativa, la regla de oro del rebase y un flujo de trabajo seguro para equipos.

Leer artículo →
Desarrollo de software

List comprehension en Python: sintaxis, ejemplos y cuándo evitarla

List comprehension en Python explicada: sintaxis, filtros, if-else, bucles anidados, tiempos medidos y cuándo es mejor un bucle for normal.

Leer artículo →