Last active
February 21, 2024 11:55
-
-
Save fercarvo/253762281445b85ac8586d7ded537559 to your computer and use it in GitHub Desktop.
A generic javascript fileless WebWorker that can execute functions, you can pass a function to be executed outside the main thread
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
/** | |
* GenericWebWorker v2.3 | |
* | |
* A Generic Javascript WebWorker that allows the user to execute and pass functions | |
* Is Fileless, for what the user does not need a file.js to request | |
* | |
* @author, Edgar Fernando Carvajal Ulloa <[email protected]>, <[email protected]> | |
* {@link https://github.com/fercarvo/GenericWebWorker} | |
*/ | |
class GenericWebWorker { | |
/** | |
* @param {any} data, Any kind of arguments that will be used in the callback, functions too | |
*/ | |
constructor(...data) { | |
this.args = data.map(a => (typeof a === 'function') ? {type:'fn', fn:a.toString()} : a) | |
} | |
//@param {function} cb, To be executed, the params must be the same number of passed in the constructor | |
async exec(cb) { | |
if (typeof cb !== 'function') | |
throw new Error(`${cb} not a function`); | |
var wk_string = this.worker.toString(); | |
wk_string = wk_string.substring(wk_string.indexOf('{') + 1, wk_string.lastIndexOf('}')); | |
var wk_link = window.URL.createObjectURL( new Blob([ wk_string ]) ); | |
var wk = new Worker( wk_link ); | |
try { | |
wk.postMessage({ callback: cb.toString(), args: this.args }); | |
var res = await new Promise((next, error) => { | |
wk.onmessage = e => (e.data && e.data.error) ? error(e.data.error) : next(e.data); | |
wk.onerror = e => error(e.message); | |
}); | |
return res | |
} catch (e) { throw e } finally { wk.terminate(); window.URL.revokeObjectURL(wk_link) } | |
} | |
//@param {function} cb, To be executed, the 1st argument is each element of the array | |
async parallel(arr, cb) { | |
var res = [...arr].map(it => new GenericWebWorker(it, ...this.args).exec(cb)) | |
return await Promise.all(res) | |
} | |
worker() { | |
onmessage = async function (e) { | |
try { | |
var cb = new Function(`return ${e.data.callback}`)(); | |
var args = e.data.args.map(p => (p.type === 'fn') ? new Function(`return ${p.fn}`)() : p); | |
try { | |
var result = await cb(...args);//If it is a promise or async function | |
return postMessage(result) | |
} catch (e) { throw `CallbackError: ${e}` } | |
} catch (e) { postMessage({error: e.message}) } | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment