Home > Back-end >  How to call a external function inside a Web Worker
How to call a external function inside a Web Worker

Time:10-08

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.

  • Related