Created
September 24, 2019 09:09
-
-
Save dirkgroenen/7fe635773a315fa287d430b3615e9e2e to your computer and use it in GitHub Desktop.
Just here for future reference, a (draft) inline web worker class.
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
/** | |
* 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