Skip to content

Instantly share code, notes, and snippets.

@dirkgroenen
Created September 24, 2019 09:09
Show Gist options
  • Save dirkgroenen/7fe635773a315fa287d430b3615e9e2e to your computer and use it in GitHub Desktop.
Save dirkgroenen/7fe635773a315fa287d430b3615e9e2e to your computer and use it in GitHub Desktop.
Just here for future reference, a (draft) inline web worker class.
/**
* Abstract class used to create and spwan inline workers.
*
* Workers can be created by extending the WebWorker class and creating
* your own implementation of 'perform()'. The extended class can then
* be used to spawn the new worker and communicate with it.
*
* @example
*
* class StorageWorker extends WebWorker {
* protected perform(this: never) {
* self.onmessage = (message) => {
* localStorage.setItem(message.data.key, message.data.data);
* }
* }
* }
*
* const worker = new StorageWorker();
*
* worker.execute();
* worker.sendMessage({
* key: 'storageKey',
* data: {some: 'data'}
* });
*/
export abstract class WebWorker<T = any> {
private worker: Worker | undefined;
constructor(readonly config?: T) { }
/**
* The code executed by the WebWorker. Note that this can't communicate with
* the class context, since it runs in the WebWorker context.
*
* Use 'self' to refer to ServiceWorkerContainer
*/
protected abstract perform(this: never, config?: T);
/**
* Creates a new worker instance for the given class and executes it.
* Further communication can be done with {@see sendMessage}
*/
execute() {
this.worker = this.createWorker();
}
/**
* Stop the current worker
*/
stop() {
if (!this.worker) {
throw new Error('Missing active worker. Make sure you call `execute()` first.');
}
this.worker.terminate();
}
/**
* Send messages to the active worker. This does not take care
* of any serialization.
*
* @param data
*/
sendMessage(data: any) {
if (!this.worker) {
throw new Error('Missing active worker. Make sure you call `execute()` first.');
}
this.worker.postMessage(data);
}
/**
* Create a new inline web worker
*/
private createWorker(): Worker {
const blob = new Blob([`(${this.perform.toString()})(${JSON.stringify(this.config || {})});`], { type: 'text/javascript' });
const url = URL.createObjectURL(blob);
return new Worker(url);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment