¿Alguna vez ha necesitado ejecutar código en el navegador que tomó tanto tiempo para ejecutar su aplicación que dejó de responder por un tiempo? Con los trabajadores web de HTML5, no tendrás que volver a experimentar eso nunca más.

Los trabajadores web le permiten separar el código de ejecución prolongada y ejecutarlo independientemente de otro código que se ejecute en la página. Esto mantiene su interfaz de usuario receptiva, incluso durante operaciones complejas.

¿Qué son los trabajadores web?

Tradicionalmente, JavaScript es un lenguaje de un solo subproceso. Eso significa que no se puede ejecutar nada más mientras se ejecuta una pieza de código. Por ejemplo, si tiene un código que intenta animar un elemento DOM, el código que intenta cambiar una variable tiene que esperar a que finalice la animación antes de poder ejecutarse.

Los trabajadores web son archivos JavaScript que se ejecutan en un subproceso separado sin acceso directo al DOM.

Una forma de pensar en los trabajadores web es que son fragmentos de código que tardan mucho tiempo en ejecutarse, por lo que se los da al navegador para que los ejecute en segundo plano. Dado que ese código ahora se ejecuta en segundo plano, no afecta el JavaScript responsable de su página web.

Como efecto secundario, ya no puede interactuar directamente con el resto de su código, por lo que los trabajadores web no tienen acceso al DOM. Sin embargo, muchas otras API de navegador todavía están disponibles, incluidas las API WebSocket y Fetch.

Sin embargo, los trabajadores web no están completamente aislados del hilo principal. Cuando un trabajador necesita comunicarse con el hilo principal, puede enviar un mensaje y el hilo principal puede enviar su propio mensaje en respuesta.

¿Por qué trabajadores web?

Antes de los trabajadores web, la única forma de ejecutar JavaScript que requería mucho tiempo en el navegador era:

  • Acepte que la página no responderá por un tiempo.
  • Rompe ese código en trozos asincrónicos.

Dado que una página que no responde suele ser una mala experiencia para el usuario, puede optar por la opción asíncrona. Escribir código de esta manera significa dividirlo en partes más pequeñas que el navegador puede ejecutar mientras no maneja la interfaz de usuario. Las piezas deben ser lo suficientemente pequeñas como para que, si es necesario actualizar la interfaz de usuario, el navegador pueda terminar de ejecutar la pieza actual y atender a la interfaz de usuario.

Se agregaron trabajadores web a HTML5 para ofrecer una mejor solución a este problema. En lugar de obligarlo a ser creativo con el código asincrónico, le permiten separar una función para que se ejecute en su propio hilo aislado.

Esto facilitó a los desarrolladores escribir dicho código y también mejoró la experiencia del usuario.

Casos de uso para trabajadores web

Cualquier aplicación que requiera mucho cálculo en el lado del cliente podría beneficiarse de los trabajadores web.

Digamos, por ejemplo, que su aplicación desea generar un informe de uso y almacena todos los datos del cliente por cuestiones de privacidad.

Para generar ese informe, su aplicación web tiene que recuperar los datos, ejecutar cálculos en ellos, organizar los resultados y presentarlos al usuario.

Si intentara hacer eso en el hilo principal, el usuario no podría usar la aplicación mientras la aplicación procesaba los datos. En su lugar, puede mover parte o la totalidad de ese código a un trabajador web. Esto permite al usuario continuar usando la aplicación mientras se realizan los cálculos.

Cómo usar trabajadores web en JavaScript

los API de trabajo web define cómo utilizar trabajadores web. El uso de esta API implica crear un objeto Worker con el constructor Worker como este:

let nuevoTrabajador = Trabajador('trabajador.js');

los Trabajador constructor acepta el nombre de un archivo JavaScript como su parámetro y ejecuta el archivo en un nuevo hilo. Devuelve un objeto Worker para permitir que el subproceso principal interactúe con el subproceso de trabajo.

Los trabajadores interactúan con el hilo principal enviando mensajes de ida y vuelta. usas el postMensaje función para enviar eventos entre el trabajador y el hilo principal. Utilizar el enmensaje detector de eventos para escuchar los mensajes de la otra parte.

Aquí hay un ejemplo de código. Primero, un hilo principal podría verse así:

dejar trabajador = nuevo Trabajador('trabajador.js')
trabajador.postMessage('¡Oye!')

trabajador.enmensaje = función(mi) {
consola.log('hilo de trabajo dice', e.datos)
}

Este subproceso principal crea un objeto de trabajador de worker.js, luego le envía un mensaje con trabajador.postMessage. Luego define un detector de eventos, similar en concepto a un Oyente de eventos DOM. Se activará un evento cada vez que el trabajador envíe un mensaje al subproceso principal y el controlador registrará el mensaje del trabajador en la consola.

El código dentro del trabajador (worker.js) tiene un trabajo:

enmensaje = función(mi) {
dejar mensaje = e.datos;
consola.log('hilo principal dicho', mensaje);
postMensaje('¡Hola!')
}

Escucha los mensajes enviados desde el hilo principal, registra el mensaje en la consola y envía un mensaje de vuelta al hilo principal.

Todos los mensajes de este ejemplo han sido cadenas, pero eso no es un requisito: puede enviar casi cualquier tipo de datos como un mensaje.

El tipo de trabajadores que ha visto hasta ahora se denominan trabajadores dedicados. Solo puede acceder a ellos desde el archivo en el que los creó (están dedicados a eso). Los trabajadores compartidos son lo contrario: pueden recibir mensajes y enviar mensajes a varios archivos. Los trabajadores compartidos son conceptualmente lo mismo que los trabajadores dedicados, pero debe usarlos de manera un poco diferente.

Veamos un ejemplo. En lugar de usar el constructor Worker, cada archivo que quiera usar un trabajador compartido debe crear un objeto de trabajo usando trabajador compartido():

dejar trabajadorcompartido = nuevo SharedWorker('trabajador.js')

Sin embargo, las diferencias no se detienen ahí. Para que un archivo envíe o reciba un mensaje de un trabajador compartido, debe hacerlo accediendo a un Puerto objeto, en lugar de hacerlo directamente. Esto es lo que parece:

trabajador compartido.port.postMessage('¡Hola!')

trabajadorcompartido.port.onMessage = función(mi) {
consola.log('El trabajador compartido envió', e.datos);
}

También debe usar el objeto de puerto dentro del trabajador:

onconnect = función(mi) {
constante puerto = e.ports[0];

puerto.enmensaje = función(mi) {
consola.log('Mensaje recibido', e.datos)
puerto.postMessage('¡Hola!');
}
}

los en conexión escucha se dispara cada vez que ocurre una conexión a un puerto (cuando un enmensaje el detector de eventos está configurado en el hilo principal).

Cuando eso sucede, el código obtiene el puerto al que se acaba de conectar desde el evento de conexión y lo almacena en una variable. A continuación, el código registra el enmensaje oyente en el objeto de puerto. Luego, el código registra el mensaje en la consola y usa el puerto para enviar un mensaje de regreso al hilo principal.

Los trabajadores web mejoran la experiencia del usuario

Los trabajadores web son subprocesos de JavaScript que le permiten ejecutar fragmentos de código complejos y de larga ejecución en segundo plano. Este código evitará el bloqueo de la interfaz de usuario. El uso de trabajadores web facilita mucho la escritura de este tipo de código y mejora la experiencia para el usuario de la aplicación. Puede crear trabajadores web e interactuar con ellos mediante la API de trabajadores web.