Created
August 10, 2024 17:45
-
-
Save airbreather/3f3587e82fa96903b22cf66a6b3ab5dd to your computer and use it in GitHub Desktop.
Promisify a Web Worker?
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
type Serializable = | |
| void | |
| undefined | |
| null | |
| number | |
| bigint | |
| string | |
| boolean | |
| ReadonlyArray<Serializable> | |
| Readonly<{ [key: string]: Serializable }> | |
| ReadonlyMap<Serializable, Serializable> | |
| ReadonlySet<Serializable> | |
| Date | |
| RegExp | |
| Blob | |
| File | |
| ImageData | |
| ArrayBuffer | |
| SharedArrayBuffer; | |
const runInWorker = <Input extends Serializable, Output extends Serializable>(f: (i: Input) => Output | Promise<Output>, i?: Input) => { | |
return new Promise<Output>((resolve, reject) => { | |
const workerFn = () => self.onmessage = async (evt: MessageEvent<[string, Input]>) => postMessage(await Promise.resolve(eval(evt.data[0])(evt.data[1]))); | |
const workerCode = new Blob([`(${workerFn})()`], { type: 'application/javascript' }); | |
const worker = new Worker(URL.createObjectURL(workerCode)); | |
worker.onmessage = (ev: MessageEvent<Output>) => resolve(ev.data); | |
worker.onerror = reject; | |
worker.postMessage([`${f}`, i]); | |
}); | |
}; | |
console.log('worker says (should be 32)', await runInWorker(() => 32)); | |
console.log('worker says (should be 8n)', await runInWorker(i => i * 2n, 4n)); | |
console.log('worker says (should be 11)', await runInWorker(async i => new Promise<number>(resolve => resolve(i + 3)), 8)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is kinda crappy since you can't use any imports, but I imagine it's got to be nice to be able to write code with full TypeScript type checking and syntax highlighting right alongside the other code that calls it. I'm surprised not to find something more-or-less equivalent to this out there.