Los web workers permiten ejecutar secciones de código de archivos JavaScript en paralelo en un hilo aparte; generalmente al realizar alguna aplicación web, página web, etc, todo el código JavaScript se ejecuta el un único hilo creado por el navegador; sin embargo al realizar tareas bloqueante o de alto procesamiento es aconsejable ejecutarlas fuera de este hilo para no afectar a este hilo principal.
Los web workers ofrece un mecanismo sencillo para ejecutar código JavaScript en segundo plano.
En esta entrada veremos cómo trabajar con los web workers.
Empezando con los web workers
Como indicamos en un comienzo los web workers se ejecuta en un proceso aislado (en paralelo); además el código que deseamos ejecutar en paralelo debe encontrarse en un archivo aparte el cual será descargado de manera asíncrona; para crear nuestro web workers debemos crear un objeto a partir de la clase Worker
de la siguiente manera:
var worker = new Worker('task.js');
Con tan solo crear un objeto de la clase Worker
indicando el archivo a cargar basta para crear un web worker.
Pase de mensajes entre el hilo principal y el web worker
Además de ejecutar el código JavaScript en un hilo aparte, los web workers ofrecen un mecanismo sencillo por pase de mensajes entre este hilo o proceso aparte con el hilo principal.
Este mecanismo es muy sencillo y útil de utilizar, en donde el pase de un mensaje del hilo principal desencadena un evento en el web worker.
Para pasar un mensaje desde el hilo principal a un Worker se emplea el método postMessage()
:
valor = 50;
var myWorker = new Worker("tarea.js");
myWorker.postMessage(valor);
Y como vimos en el ejemplo anterior, este pase de mensaje en realidad nos permite pasar datos del hilo principal al Worker
.
Para poder ver los mensajes que devuelve el Worker
al hilo principal se emplea la propiedad onmessage
:
valor = 50;
var myWorker = new Worker("tarea.js");
myWorker.postMessage(valor);
myWorker.onmessage = function (oEvent) {
console.log("Números primos : " + oEvent.data);
};
Ejemplo práctico: Worker para generar números primos
El siguiente código JavaScript permite determinar todos los primos que existen desde el cero hasta un valor dado:
function checkPrimo(number) {
var divisor = 1;
var primo = 0;
for (var i = 0; i <= number; i++) {
if (number % i == 0) {
primo++;
}
if (primo > 2)
break;
}
if (primo == 2) {
return true;
}
else {
return false;
}
}
// funcion para determinar si un conjunto de numeros es primo
function checkPrimoCota(number) {
primos = "";
for (i = 0; i <= number; i++) {
if (checkPrimo(i))
primos += i + " ";
}
return primos;
}
Y al pasar un mensaje al web worker desde nuestra página principal:
postMessage("¡Empezando a trabajar!");
onmessage = function (oEvent) {
postMessage("Recibido el siguiente valor: " + oEvent.data);
postMessage("Los siguientes son primos:" + checkPrimoCota(oEvent.data))
};
Vea el ejemplo práctico en los enlaces de descarga al inicio y final de esta entrada.
Errores manejados por los Workers
Al igual que ocurre con el pase de mensajes, para manejar los errores se debe de emplear una propiedad llamada onerror
:
valor = 50;
var myWorker = new Worker("tarea.js");
myWorker.postMessage(valor);
myWorker.onmessage = function (oEvent) {
console.log("Números primos : " + oEvent.data);
};
myWorker.onerror = function (oEvent) {
console.log("A ocurrido un error en el archivo: " + oEvent.filename+" en la línea "+oEvent.lineno+" "+oEvent.message);
};
En donde:
filename
: Nombre del script que ocasionó el error.message
: Error ocasionado.lineno
: Línea en donde ocurrió el error.
Consideraciones acerca de los web workers
Los web workers NO pueden acceder a:
- DOM.
- Objeto window.
- Objeto document.
- Objeto parent.
Es necesario que el código JavaScript a ser ejecutado por los web workers se encuentren en archivos apartes.
Para cerrar los web workers empleamos el método close
.
Para verificar el soporte de los navegadores de los web workers:
if(typeof(Worker) !== "undefined") {
// Soporta los Web worker
// Crear nuestros web workers
} else {
// No soporta los Web worker
}
Conclusiones
Los web workers pueden convertirse en una gran herramienta para evitar procesos bloqueantes en nuestro JavaScript, al lograr ejecutar código en paralelo podemos lograr un mejor desempeño de nuestras aplicaciones web.
Puedes ver el ejemplo completo en los siguientes enlaces:
Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter