Skip to content

Instantly share code, notes, and snippets.

@dfkaye
Last active June 13, 2024 08:32
Show Gist options
  • Save dfkaye/b78d6ecf80aedc6c159829725b181268 to your computer and use it in GitHub Desktop.
Save dfkaye/b78d6ecf80aedc6c159829725b181268 to your computer and use it in GitHub Desktop.
pass functions to workers and and call them in subsequent messages
// 8 June 2024
// pass functions to workers and and call them in subsequent messages.
// similar to gists in 2022:
// pass functions as strings to workers and revive them with the Function() constructor
// https://gist.github.com/dfkaye/527f163b6913b163a579bbeb01858593
// Not the same as "pass a stringified function in its own blob to a worker and
// import it using importScripts(blobUrl)."
// https://gist.github.com/dfkaye/ca9722cd247c6d907b3bbaf7273741e0
var source = `
self.onmessage = function (request) {
var { action, value } = Object(request.data);
if (action == 'extend') {
extend({name, fn} = value)
}
else if (action in actions) {
actions[action](...value);
}
};
extend = function ({name, fn}) {
actions[name] = Function("return (" + fn + ").apply(0, arguments)");
self.postMessage({
action: "extended",
value: {
name,
fn: actions[name].toString()
}
});
// console.log(actions[name])
};
actions = {}
`;
var blob = new Blob([source], {type: "text/javascript"});
var url = URL.createObjectURL(blob);
var worker = new Worker(url);
worker.onmessage = function (response) {
var { action, value } = Object(response.data)
console.warn("calling back:", action);
if (action == 'extended') {
console.warn("new function added: ", value.name, value.fn);
}
else {
console.warn(action, value);
}
};
/* test it out */
function test(a,b,c) {
console.info("testing", a,b,c);
self.postMessage({ action: "tested", value: a+b+c });
};
worker.postMessage({
action: "extend",
value: {
name: "test",
fn: test.toString()
}
});
setTimeout(() => {
worker.postMessage({
action: "test",
value: ["A", "B", "C"]
});
}, 1000);
setTimeout(() => {
worker.postMessage({
action: "test",
value: ["D", "E", "F"]
});
}, 1000);
/*
calling back: extended
new function added: test function anonymous(
) {
return (function test(a,b,c) {
console.info("testing", a,b,c);
self.postMessage({ action: "tested", value: a+b+c });
}).apply(0, arguments)
}
testing A B C
calling back: tested
tested ABC
testing D E F
calling back: tested
tested DEF
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment