Last active
January 23, 2025 08:19
-
-
Save gitawego/eba2712acd347b30c5865e293a4bce6d to your computer and use it in GitHub Desktop.
webworker
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* example of worker (ex: worker.ts) | |
* | |
* ```ts | |
* self.addEventListener('message', (event) => { | |
const { eventName, data, messageId } = event.data; | |
switch (eventName) { | |
case 'double': | |
const result = data * 2; | |
self.postMessage({ eventName,messageId, result }); | |
break; | |
case 'square': | |
const squared = data * data; | |
self.postMessage({ eventName,messageId, result: squared }); | |
break; | |
default: | |
self.postMessage({ eventName,messageId, error: 'Unknown event name' }); | |
} | |
}); | |
`*`` | |
*/ | |
export class WebWorker<D extends object> { | |
constructor(readonly worker: Worker) {} | |
uuid(): string { | |
try { | |
return crypto.randomUUID(); | |
} catch (err) { | |
return `${Date.now()}`; | |
} | |
} | |
sendMessageToWorker<R = any, K extends keyof D = keyof D>( | |
eventName: K, | |
data?: D[K], | |
timeout = 5e3 | |
): Promise<R> { | |
return new Promise((resolve, reject) => { | |
const messageId = `${eventName as string}-${this.uuid()}`; | |
let timer: NodeJS.Timeout; | |
const handleMessage = (event: MessageEvent) => { | |
if ( | |
event.data.eventName === eventName && | |
event.data.messageId === messageId | |
) { | |
clearTimeout(timer); | |
this.worker.removeEventListener('message', handleMessage); | |
if (event.data.error) { | |
reject(new Error(event.data.error)); | |
} else { | |
resolve(event.data.result); | |
} | |
} | |
}; | |
this.worker.addEventListener('message', handleMessage); | |
if (timeout && timeout > 0) { | |
timer = setTimeout(() => { | |
this.worker.removeEventListener('message', handleMessage); | |
reject( | |
new Error( | |
`Timeout: No response for event "${eventName as string}" within ${timeout}ms` | |
) | |
); | |
}, timeout); | |
} | |
this.worker.postMessage({ eventName, data, messageId }); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment