Concurrencia con Javascript

Los workers

Aunque Javascript ejecuta los procesos en modo unithread (una sola secuencia de ejecución) puede crear procesos que funcionen de manera concurrente, con los que se puede comunicar mediante eventos e intercambio de mensajes.

Para eso Javascript utiliza los Workers, procesos que se ejecutan de forma concurrente bajo el control del navegador. Los workers pueden intercambiar datos con el script que los invoca.

Los workers no pueden acceder al DOM de la página donde se encuentra el sript principal, el que los crea. Su código se almacena en un archivo independiente.

En el contexto de Javascript los Workes no son más que objetos, se pueden crear y destruir.

Para la forma de usarlo vamos a por un ejemplo sencillo: un worker que se va a encargar de contar, el resultado de esta tarea se va a reflejar en la página de script principal.

Código del Worker, en un archivo de nombre contador.js

function contar(contador){

    if(contador < 1000){

        postMessage(contador);

        setTimeout(contar,1000, contador+1);

        }

}

contar(0);

El script principal podria ser algo así , en una página que puedes llamar master.htm

<div id="tit"></div>

<div id="contar"></div>

<script>

var miworker = new Worker("contador.js");

miworker.onmessage(()=>document.getElementById("contar").innerHTML = event.data);

document.getElementById("tit").innerHTML = "Llamando a un worker";

</script>

Si creas esta página, al abrirla con el navegador verás que en el div contar aparece un contador. El script puede contener más instrucciones y seguir trabajando si fuera necesario, sin ningún tipo de interrupción. El worker trabaja de manera independiente.

 flujo del worker

El funcionamiento es muy simple se crea el objeto Worker con el operdor new, el único argumento necesario es la url del javascript que se ejecuta en este proceso.

Cuando el objeto envía un mensaje de vuelta al script padre, mediante el método postMessage(data), en la página se genera un evento miworker.sendmessage. El manejador de este evento proceso el mensaje cuyo contenido está en event.data.

En el ejemplo el evento message lee el dato desde miworker, este dato viene en el objeto event: event.data, y lo muestra en un bloque div cuyo id es contar

Una tarea Worker puede finalizarse mediante el método worker.terminate(), con este método la tarea concurrente es finalizada de inmediato, sin dejarla acabar.

 

Resumiendo

Los Worker son objetos que permiten que los programas escritos con Javascript puedan usar procesos concurrentes.

Existe comunicación entre un objeto Worker y el script que lo crea: eventos e intercambio de datos.

El método para enviar datos es el postMessage(dato). El dato puede ser de cualquier tipo: primitivos u objetos, pero solo se puede enviar o recibir un solo dato.

Para poder intercambiar más de un dato se pueden usar objetos JSON u objetos javascript.

Para recibir datos tanto el worker como la página que lo crea usan el evento onmessage().

La información intercambiada se encuentra en la propiedad event.data.

Los workers no pueden modificar ni acceder al DOM de la página que los crea, pero mediante el intercambio de datos pueden ordenar al script principal que altere su DOM.

Aunque no tienen acceso al DOM si pueden acceder a multiples servicios o apis del navegador como pueden ser

  • XHR API (para Ajax)
  • Fetch API (alternativa al Ajax)
  • BroadcastChannel API
  • FileReader API
  • IndexedDB
  • Notifications API
  • Promises
  • Channel Messaging API
  • Cache API
  • Console API
  • Temporizadores Javascript
  • Modelo de eventos
  • WebSockets
  • WebGL
  • Animaciones SVG