Web Workers#

JavaScript, inicialmente un lenguaje de ejecución de un solo hilo, ha evolucionado para manejar tareas pesadas mediante técnicas como las Web APIs y los Web Workers. Los Web Workers permiten ejecutar scripts en segundo plano, en un hilo separado al principal, mejorando así la capacidad de respuesta y el rendimiento de las aplicaciones web modernas. Sirven para evitar bloqueos en el hilo principal de ejecución y mejorar la experiencia del usuario.

Tipos de Web Workers#

  1. Dedicated Workers: Estos son los más comunes y se ejecutan en un hilo dedicado al contexto del script que los creó. No comparten recursos con otros scripts y son útiles para tareas intensivas que requieren mucho procesamiento.

  2. Shared Workers: Pueden ser compartidos por varios scripts ejecutándose en diferentes ventanas, pestañas o iframes dentro del mismo dominio. Son ideales para aplicaciones que necesitan coordinar tareas entre múltiples instancias de la misma aplicación web.

  3. Service Workers: Actúan como servidores proxy que se ejecutan en segundo plano y gestionan eventos de red como las peticiones HTTP. Son esenciales para crear aplicaciones web progresivas (PWAs) que funcionen sin conexión y mejoren la velocidad de carga.

Ejemplo de Uso: Dedicated Worker#

A continuación, un ejemplo práctico que muestra cómo utilizar un Dedicated Worker para generar números primos de manera asíncrona y eficiente:

Código en el programa principal (main.js)#

// Crear un nuevo Dedicated Worker desde un archivo externo
const worker = new Worker('./generate.js');

// Enviar un mensaje al worker para iniciar la generación de números primos
worker.postMessage({
   command: 'generate',
   quota: 10000000
 });

// Escuchar la respuesta del worker
worker.addEventListener('message', (message) => {
   console.log('Primes generated:', message.data);
});

Código en el Dedicated Worker (generate.js)#

// Función para verificar si un número es primo
function isPrime(n) {
   for (let c = 2; c <= Math.sqrt(n); ++c) {
       if (n % c === 0) {
           return false;
       }
   }
   return true;
}

// Función para generar números primos hasta alcanzar una cuota especificada
function generatePrimes(quota) {
   const primes = [];
   const maximum = 1000000;

   while (primes.length < quota) {
       const candidate = Math.floor(Math.random() * (maximum + 1));
       if (isPrime(candidate)) {
           primes.push(candidate);
       }
   }

   // Enviar los números primos generados de vuelta al programa principal
   postMessage(primes);
}

// Escuchar mensajes enviados desde el programa principal
addEventListener("message", (message) => {
   if (message.data.command === 'generate') {
       generatePrimes(message.data.quota);
   }
});

En este ejemplo:

  • El programa principal (main.js) crea un nuevo Dedicated Worker utilizando el archivo generate.js.

  • Envía un mensaje al worker con el comando 'generate' y la cuota de números primos que se deben generar.

  • El Dedicated Worker (generate.js) escucha el mensaje, genera los números primos de manera asíncrona utilizando funciones definidas localmente (isPrime y generatePrimes), y envía los resultados de vuelta al programa principal mediante postMessage.