Trabajador Web en TypeScript

Trabajador Web en TypeScript

Este artículo explica los Trabajadores Web en TypeScript.

Puede aprender sobre el concepto de Web Workers y varios consejos de uso con ejemplos.

YouTube Video

Trabajador en TypeScript

En TypeScript, un Worker es un mecanismo para realizar procesamiento en segundo plano, separado del hilo principal, aprovechando la API de Trabajadores Web de JavaScript. Esto permite ejecutar cálculos intensivos y tareas asíncronas sin afectar el funcionamiento de la interfaz de usuario.

Un Worker opera en paralelo con el hilo principal (hilo de la interfaz de usuario) y puede intercambiar datos entre hilos mediante mensajes. Incluso en TypeScript, puedes utilizar Worker mientras escribes código seguro en tipos.

Uso Básico de un Trabajador

  1. Creando un Trabajador

    Crea una instancia de Worker y ejecuta el script especificado. Normalmente, el script se define en un archivo separado.

  2. Intercambio de Mensajes

    Envía y recibe mensajes entre el hilo principal y el hilo Worker utilizando postMessage y onmessage.

Ejemplo: Implementación Básica de un Trabajador

  1. worker.ts: Script para Trabajador
1// worker.ts
2self.onmessage = (event) => {
3    const data = event.data;
4    const result = data.num1 + data.num2;
5    self.postMessage(result); // Return the result to the main thread
6};
  1. main.ts: Script para usar un Trabajador en el Hilo Principal
 1// main.ts
 2const worker = new Worker(
 3    new URL('./worker.ts', import.meta.url),
 4    { type: 'module' }
 5);
 6
 7worker.onmessage = (event) => {
 8    console.log("Result from worker:", event.data); // Receive message from the worker
 9};
10
11worker.postMessage({ num1: 10, num2: 20 }); // Send message to the worker
  • En este ejemplo, worker.ts se ejecuta en un hilo separado, calcula la suma de num1 y num2, y la devuelve al hilo principal. El hilo principal recibe el resultado y lo muestra en la consola.
  • Cuando especificas type: 'module', el script del Worker se interpreta como un módulo ES, lo que te permite usar import y export. Esto te permite manejar estructuras de módulos sin utilizar el tradicional importScripts().

Puntos a Considerar al Usar Trabajadores en TypeScript

Añadiendo Definiciones de Tipos

En TypeScript, define tipos de datos para asegurar una interacción segura en tipos durante el envío y recepción de mensajes.

 1// Define data types
 2interface WorkerData {
 3    num1: number;
 4    num2: number;
 5}
 6
 7interface WorkerResult {
 8    result: number;
 9}
10
11// worker.ts
12self.onmessage = (event: MessageEvent<WorkerData>) => {
13    const data = event.data;
14    const result = data.num1 + data.num2;
15    const message: WorkerResult = { result };
16    self.postMessage(message); // Send the result in a type-safe manner
17};
18
19// main.ts
20const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
21
22// Type the event from the worker
23worker.onmessage = (event: MessageEvent<WorkerResult>) => {
24  console.log("Result from worker:", event.data); // event.data is number
25};
26
27// Send typed data to the worker
28const message: WorkerData = { num1: 10, num2: 20 };
29worker.postMessage(message);
  • Al especificar el parámetro de tipo de MessageEvent, puedes definir claramente el tipo de datos a recibir. Esto permite intercambiar datos con seguridad en tipos.

Configuración de Webpack o Vite

Cuando se utiliza Worker en TypeScript, puede ser necesario recurrir a empaquetadores como Webpack o Vite. Al usar estas herramientas, puede empaquetar correctamente el script de Worker y hacerlo disponible desde el hilo principal.

Por ejemplo, al usar Vite, utilice import.meta.url para importar correctamente el Worker.

1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
  • Esto asegura que el script empaquetado del Worker se cargue correctamente, permitiendo el procesamiento con Worker.

Consideraciones para el Mensajeo y la Concurrencia

  1. Copia de Datos

    Al enviar y recibir mensajes entre el hilo principal y el hilo Worker, los datos se copian. Al trabajar con datos complejos como objetos, es necesario considerar la eficiencia. Intercambiar grandes cantidades de datos con frecuencia puede degradar el rendimiento.

  2. Objetos Transferable

    Algunos objetos, como ArrayBuffer, se denominan objetos Transferible. Los objetos Transferible pueden transferirse al Worker en lugar de ser copiados durante la mensajería. Esto le permite evitar la sobrecarga de la copia de datos.

1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
2
3const buffer = new ArrayBuffer(1024);
4worker.postMessage(buffer, [buffer]); // Transfer ownership to the Worker
5
6console.log(buffer.byteLength); // 0 (ownership moved)
  • Al pasar [buffer] como segundo argumento a worker.postMessage(), el buffer se transfiere al Worker en lugar de ser copiado.

  • Después de esto, el buffer en el hilo principal queda vacío (con byteLength 0) y solo puede ser utilizado por el Worker.

Finalizando un Worker

El Worker debe finalizarse después de su uso para minimizar el consumo de memoria. Puede finalizar un Worker utilizando el método terminate.

1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
2// ...
3
4worker.terminate(); // Terminate the Worker
  • Este código termina el Worker utilizando el método terminate.

Manejo de Excepciones en Worker

Si ocurre un error dentro de un Worker, puede manejarlo utilizando el evento onerror.

1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
2
3worker.onerror = (error) => {
4    console.error("Error in Worker:", error.message);
5};
  • Este código captura y maneja los errores que ocurren dentro del Worker utilizando el evento onerror.

Resumen

Al usar Worker en TypeScript, puede ejecutar tareas pesadas en segundo plano mientras mantiene fluido el hilo principal. Al utilizar definiciones de tipo, los intercambios de mensajes también se pueden realizar de manera segura en cuanto a tipos. Al prestar atención al intercambio de datos y a la gestión de hilos, puede lograr mejoras en el rendimiento y una concurrencia eficiente.

Puedes seguir el artículo anterior utilizando Visual Studio Code en nuestro canal de YouTube. Por favor, también revisa nuestro canal de YouTube.

YouTube Video