Skip to content
This repository has been archived by the owner on Apr 1, 2020. It is now read-only.

Feature/add workerize utility #2617

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions browser/src/Workerize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
interface IArgs<T> {
data: T
}

type Callback<T> = (args?: T) => any

/**
* Takes a CPU intensive function
* passes it off to a dynamically generated WebWorker
* and returns a promise to resolve the return value of the function
*
* limitations: function has to be Pure! -> no external dependencies etc.
* @name workerize
* @function
* @param Callback<T>
* @param args?: T
* @returns Promise<R>
*/
export function workerize<T, R>(work: Callback<T>, args?: T) {
const handleResult = ({ data }: IArgs<T>) => {
const result = work(data)
const webWorker: Worker = self as any
return webWorker.postMessage(result)
}

// courtesy of this gem -
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice find!

// https://stackoverflow.com/questions/42773714/is-async-await-truly-non-blocking-in-the-browser
// writes the contents of the string passed in to a file and executes it.
const blob = new Blob([`var work = ${work};\n onmessage = ${handleResult.toString()}`], {
type: "text/javascript",
})
const worker = new Worker(URL.createObjectURL(blob))
worker.postMessage(args)
return new Promise<R>(resolve => (worker.onmessage = evt => resolve(evt.data)))
}