¿Cómo Funciona el Asincronismo en JavaScript Si Es Sincrónico?

¿Cómo Funciona el Asincronismo en JavaScript Si Es Sincrónico?

Introducción

Miguel Ángel Durán García en LinkedIn: Aprende Promesas y asincronía en JS  con…

JavaScript es un lenguaje de programación sincrónico y monohilo, lo que significa que ejecuta una tarea a la vez en el orden en que fueron escritas. Sin embargo, si solo trabajara de manera estrictamente sincrónica, sería ineficiente para manejar tareas que toman tiempo, como llamadas a APIs, consultas a bases de datos o la carga de archivos. Aquí es donde entra el asincronismo en JavaScript, que permite que ciertas tareas se realicen sin bloquear la ejecución del resto del código. En este artículo, explicaremos cómo funciona el asincronismo en un lenguaje sincrónico como JavaScript y exploraremos los principales mecanismos asincrónicos como los callbacks, promesas y async/await.

¿Cómo es JavaScript Sincrónico?

JavaScript es sincrónico por naturaleza, lo que significa que ejecuta las tareas de manera secuencial, una después de otra. Si una función toma demasiado tiempo en completarse, bloqueará la ejecución de otras hasta que termine. Este comportamiento, en un entorno como un navegador o un servidor con Node.js, no es ideal, ya que puede llevar a tiempos de espera largos o interfaces de usuario bloqueadas.

Ejemplo de Código Sincrónico

				
					console.log("Primero");
console.log("Segundo");
console.log("Tercero");
				
			

En este caso, el código se ejecuta en orden, de forma lineal, porque cada tarea se completa inmediatamente.

Pero, ¿qué sucede cuando una de esas tareas toma más tiempo, como una solicitud de red?

Ejemplo con Tarea Lenta

				
					console.log("Primero");

setTimeout(() => {
  console.log("Segundo");  // Se ejecutará después de 2 segundos
}, 2000);

console.log("Tercero");
				
			

Aquí, a pesar de que hemos escrito el setTimeout() entre las dos sentencias console.log, la tarea asincrónica no bloquea el flujo principal. JavaScript primero imprime «Primero» y «Tercero» mientras la tarea asincrónica (el temporizador) se ejecuta en segundo plano. Este es el comportamiento asincrónico de JavaScript.

El Asincronismo en JavaScript

JavaScript logra asincronismo a través del Event Loop, que permite que las tareas que toman tiempo se realicen sin bloquear el hilo principal. Aunque JavaScript solo puede ejecutar una tarea a la vez debido a su naturaleza monohilo, las tareas que involucran temporizadores, eventos o solicitudes de red pueden delegarse a un sistema de APIs del navegador o Node.js.

El Event Loop actúa como un mecanismo que monitorea el Call Stack y la Task Queue. Cuando una tarea asincrónica termina (como una solicitud de red), su callback se coloca en la Task Queue y el Event Loop la ejecuta cuando el Call Stack está vacío.

Mecanismos de Asincronismo en JavaScript

JavaScript proporciona varias herramientas para manejar el asincronismo. Estas incluyen los callbacks, promesas, y async/await.

1. Callbacks

Los callbacks son funciones que se pasan como argumento a otra función y se ejecutan una vez que se completa una tarea asincrónica. Los callbacks fueron la primera forma de manejar asincronismo en JavaScript, pero tienen problemas de legibilidad, especialmente cuando se anidan muchos callbacks, creando lo que se conoce como «Callback Hell».

Ejemplo con Callback

				
					function tareaAsincrona(callback) {
  setTimeout(() => {
    console.log("Tarea Asincrónica Completa");
    callback();
  }, 2000);
}

tareaAsincrona(() => {
  console.log("Callback ejecutado");
});
				
			

2. Promesas

Las promesas fueron introducidas para resolver algunos de los problemas de los callbacks, como la dificultad de manejar errores y el código anidado. Una promesa es un objeto que representa una operación asincrónica que puede completarse o fallar en el futuro. El método then() se utiliza para manejar el éxito, y catch() para manejar errores.

Ejemplo con Promesa

				
					const promesa = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("Promesa resuelta");
  }, 2000);
});

promesa
  .then((resultado) => {
    console.log(resultado);
  })
  .catch((error) => {
    console.log(error);
  });
				
			

3. Async/Await

Async/await es la forma más moderna y sencilla de manejar código asincrónico en JavaScript. Introducido en ES8 (ECMAScript 2017), permite escribir código asincrónico que se lee como si fuera sincrónico. Async convierte una función en una promesa, y await pausa la ejecución hasta que la promesa se resuelve.

Ejemplo con Async/Await

				
					function promesaAsincrona() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve("Promesa resuelta con async/await");
    }, 2000);
  });
}

async function ejecutarAsync() {
  const resultado = await promesaAsincrona();
  console.log(resultado);
}

ejecutarAsync();
				
			

El Event Loop: El Corazón del Asincronismo

El Event Loop es el mecanismo clave que hace posible el asincronismo en un lenguaje que es monohilo y sincrónico. A través del Call Stack (pila de llamadas), las tareas sincronas se ejecutan de forma secuencial. Sin embargo, cuando se encuentra una tarea asincrónica, esta se delega a las APIs del entorno (como la API de setTimeout(), fetch(), etc.).

Una vez que la tarea asincrónica termina, se coloca su callback en la Task Queue. El Event Loop supervisa el Call Stack, y cuando está vacío, recoge la tarea de la Task Queue y la coloca en el Call Stack para ejecutarla.

Diagrama Simplificado del Event Loop:

  1. Call Stack: Donde las funciones se apilan para ser ejecutadas.
  2. Web APIs/Node APIs: Donde las operaciones asincrónicas se gestionan.
  3. Task Queue: Donde se colocan las tareas completadas para ser ejecutadas.
  4. Event Loop: Verifica si el Call Stack está vacío y, si es así, mueve las tareas desde la Task Queue.

Conclusión

Aunque JavaScript es sincrónico y monohilo, su modelo de asincronismo basado en el Event Loop permite que se manejen tareas complejas como llamadas a APIs, temporizadores y eventos sin bloquear el flujo de ejecución. Entender cómo funcionan los callbacks, promesas y async/await es esencial para escribir código JavaScript eficiente y evitar el bloqueo del hilo principal. Con estas herramientas, puedes manejar de manera efectiva operaciones asincrónicas y mejorar la experiencia del usuario.

Links de referencia: Javascript Asíncrono: La guía definitivaJavaScript asíncronoAsincronismo en JsIntroducción a JavaScript asíncrono

Facebook
X
LinkedIn
Reddit
Pinterest
Threads

Post relacionados

Post recientes

Search