angular2-web-worker
angular2-web-worker copied to clipboard
Allow asynchronous work in the worker
Hi Haochi!
First of all, thank you for the library! It is really easy to use and it saves a lot of time.
In my project, we want to convert files to base64 strings. As these operations can be really heavy, I wanted to do the work in a webworker. The issue I've been dealing with is that the conversion to a string is asynchronous and your library doesn't let us do asynchronous work in the worker.
I implemented my own solution but I wonder if that wouldn't be useful for other people to have it included in your library?
Temporal solution
It consists in extending your service and overriding the createWorkerUrl
method to pass postMessage
as an argument :
import { WebWorkerService as service } from 'angular2-web-worker';
export class WebWorkerService extends service {
// We override the method to enable postMessage to be called whenever we want
// This allows us to asynchronously trigger postMessage
private createWorkerUrl(resolve: Function): string {
const resolveString = resolve.toString();
// The change is here: postMessage is passed as argument
const webWorkerTemplate = `
self.addEventListener('message', function(e) {
(${resolveString})(postMessage, e.data);
});
`;
const blob = new Blob([webWorkerTemplate], { type: 'text/javascript' });
return URL.createObjectURL(blob);
}
}
Then I use it this way:
import { WebWorkerService } from 'app/services/webworker.service';
export class Example {
// [...]
// This method is called at some point
async convertFile(file: File) {
const base64 = await this.webWorkerService.run(this.workerFunction, file);
console.log(base64);
}
workerFunction(postMessage: Function, file: File): void {
const fileReader = new FileReader();
fileReader.addEventListener('load', ({ target}: Event) => {
postMessage((<FileReader>target).result);
});
fileReader.readAsDataURL(file);
}
}
Thank you!
@clementprdhomme Ahh interesting. I haven't thought of this use case. I will play around with your implementation. Thanks!
Hi @haochi , Any update on this? Are you planning to implement the asynchronous implementation in the worker? My use case needs it too, so for now I am going with @clementprdhomme solution.
@navcoder just started a new job this week. I will try to add support over the weekend 😅
Thanks @haochi . One more thing, I am using tyepscript+ gulp + SystemJs for module loading. After installing angular2-web-worker using npm install, it created a folder named "angular2-web-worker" inside node_modules. But when trying to import in my app.component using import { WebWorkerService } from 'angular2-web-worker'; it doesn't recognize this module. So I had to manually add an index.d.ts file inside the "angular2-web-worker" folder containing line export { WebWorkerService } from './web-worker.service'; Now my app.component.ts recognizes the module. Am I doing it the right way or missing something?
So.. this is still unimplemented.
@christofferfleat Feel free to submit a PR.