diff --git a/src/hooks/useWorker/useWorker.ts b/src/hooks/useWorker/useWorker.ts index cb58e9d..dd1bfeb 100644 --- a/src/hooks/useWorker/useWorker.ts +++ b/src/hooks/useWorker/useWorker.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { MutableRefObject, useCallback, useRef, useState } from 'react'; import { validators } from '@/utils'; @@ -51,19 +52,19 @@ const useWorker = ( safeWorkerHelper((worker) => { // 작업이 완료된 스레드로부터 이벤트 수신 #1 - worker.current.onmessage = ( - e: MessageEvent - ) => { - const payload = e.data; + worker.current.onmessage( + (e: MessageEvent) => { + const payload = e.data; - if (payload?.error) { - console.error(payload.error); + if (payload?.error) { + console.error(payload.error); + clearWorker(); + } + + setResult(payload); clearWorker(); } - - setResult(payload); - clearWorker(); - }; + ); // 작업을 수행할 작업 스레드로 인수 전달 #2 worker.current.postMessage([args, closure]); @@ -84,7 +85,10 @@ const useWorker = ( export default useWorker; -class FunctionWorker extends Worker { +class FunctionWorker { + worker: Worker | null = null; + workerBlob: Blob | null = null; + constructor(workerScript: WorkerScript) { if (!validators.isClient() || !window.Worker || !globalThis.Blob) { throw new WebWorkerError("Your browser doesn't support web workers."); @@ -99,7 +103,7 @@ class FunctionWorker extends Worker { // this === DedicatedWorkerGlobalScope const workerFunction = (script: WorkerScript) => { // 작업 스레드로 전달된 인수 수신 #2 - this.onmessage = async ({ data }: MessageEvent<[A, C]>) => { + this.onmessage(async ({ data }: MessageEvent<[A, C]>) => { try { // 작업 수행 const workerResult = await script(data[0], data[1]); @@ -109,31 +113,40 @@ class FunctionWorker extends Worker { } catch (error) { this.postMessage({ error }); } - }; + }); }; try { - const workerBlob = new Blob( + this.workerBlob = new Blob( [`(${workerFunction.toString()})(${workerScript.toString()})`], { type: 'application/javascript' } ); - - super(URL.createObjectURL(workerBlob)); + this.worker = new Worker(URL.createObjectURL(this.workerBlob)); } catch (error) { throw new WebWorkerError( `Failed to create workerBlob: ${error instanceof Error ? error.message : 'unknown error'}` ); } } -} -const validateRef = (workerRef: MutableRefObject) => { - return (action: (arg: MutableRefObject) => void) => { - if (workerRef.current) { - action(workerRef as MutableRefObject); + onmessage(callback: (message: MessageEvent) => any) { + if (this.worker) { + this.worker.onmessage = callback; } - }; -}; + } + + postMessage(message: any): void { + if (this.worker) { + this.worker.postMessage(message); + } + } + + terminate(): void { + if (this.worker) { + this.worker.terminate(); + } + } +} class WebWorkerError extends Error { constructor(message: string) { @@ -142,3 +155,11 @@ class WebWorkerError extends Error { this.name = 'WebWorkerError'; } } + +const validateRef = (workerRef: MutableRefObject) => { + return (action: (arg: MutableRefObject) => void) => { + if (workerRef.current) { + action(workerRef as MutableRefObject); + } + }; +};