Skip to content

Instantly share code, notes, and snippets.

@XoseLluis
Created August 6, 2018 14:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save XoseLluis/96060c1055d2b54280464cb99eef2b25 to your computer and use it in GitHub Desktop.
Save XoseLluis/96060c1055d2b54280464cb99eef2b25 to your computer and use it in GitHub Desktop.
Web Wroker returning a Promise. Sort of .Net Task.Run
class PromiseWorkerHelper{
constructor(){
//one shot object, we create it and invoke its run method just once
this.alreadyCalled = false;
//this.worker = new Worker("WebWorkerCode.js");
this.worker = this._createWorkerFromString();
//this is executed when the worker posts a message
this.worker.onmessage = (msg) => this.resolveFunc(msg.data);
this.worker.onerror = (msg) => this.rejectFunc(msg);
this.resolveFunc = undefined;
this.rejectFunc = undefined;
}
_createWorkerFromString(){
let workerOnmessageHandler = function(e){
console.log('Message received from main script');
let fnSt = e.data[0];
console.log("fnSt: " + fnSt);
let args = e.data[1];
//we need the () trick for eval to return the function
let fn = eval("(" + fnSt + ")");
let workerResult = fn(...args);
console.log('Posting result back to main script: ' + workerResult);
postMessage(workerResult);
};
let str = "onmessage = " + workerOnmessageHandler.toString() + ";";
let blob = new Blob([str], {type: 'application/javascript'});
return new Worker(URL.createObjectURL(blob));
}
run(fn, ...args){
if (this.alreadyCalled){
throw "already used once";
}
this.alreadyCalled = true;
let pr = new Promise((resolve, reject) => {
this.resolveFunc = resolve;
this.rejectFunc = reject;
});
this.worker.postMessage([fn.toString(), args]);
return pr;
}
}
function longFormatting(txt, formatCharacter){
console.log("starting longFormatting");
let res = formatCharacter + txt + formatCharacter;
start = Date.now();
while(Date.now() - start < 1000){}
console.log("finishing longFormatting");
return res;
}
function main(){
document.getElementById("launchCalculationBt").addEventListener("click", async () => {
console.log("Main.js, inside button handler");
let txt = "hello";
let formatCharacter = "---";
//this does not work, I can not post a funtion to a webWorker, I have to stringify it
// //trap in a closure the arguments to the function
// let longFormattingClosure = () => {
// return longFormatting(txt, formatCharacter);
// };
// let promise = new PromiseWorkerHelper().run(longFormattingClosure);
let promise = new PromiseWorkerHelper().run(longFormatting, txt, formatCharacter);
let res = await promise;
console.log("Main.js, result: " + res);
});
}
window.addEventListener("load", main, false);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment