I'm learning about Web Worker and today I needed make a external function work inside a Web Worker like this:
main.js:
function doSomething(parameter){
//Doing something
}
if (window.Worker) {
const myWorker = new Worker("worker.js");
myWorker.postMessage("Hello World");
} else {
console.log('Your browser doesn\'t support web workers.');
}
worker.js:
onmessage = function(e) {
doSomething(e.data)
}
Have a way to do this work?
CodePudding user response:
Everything you send to a web worker has to be serializable. As a function is not, you can't use the callback pattern as you probably would like to do.
The only solution is to send a message back to the main thread just like you did with postMessage
, and the main thread has to acknowledge that message with the message
event listener and execute the doSomething
function on its own.
CodePudding user response:
It's a bit hacky, but depending on your use case, you can do something like the following:
// main.js
const doSomething = (param) => {
return param '!!!'
}
const worker = new Worker("worker.js")
worker.postMessage({
fn: doSomething.toString(),
param: "Hello World",
})
worker.onmessage = (e) => {
console.log(e.data) // logs "Hello World!!!"
}
// worker.js:
self.onmessage = (e) => {
const { fn, param } = e.data
const result = eval(`(${fn})`)(param)
self.postMessage(result)
}
Note that eval
is generally best avoided, but it can be safe here as long as doSomething
is trusted code.
Note also that this will fail if doSomething
relies on dependencies external to itself; all such dependencies will need to be serializable and passed explicitly as parameters, via the same postMessage
mechanism.