Как вызвать внешнюю функцию внутри веб-работника

#javascript #web-worker

Вопрос:

Я изучаю веб-работника, и сегодня мне нужно было заставить внешнюю функцию работать внутри веб-работника, как это:

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)
}
 

У вас есть способ выполнить эту работу?

Ответ №1:

Все, что вы отправляете веб-работнику, должно быть сериализуемым. Поскольку функции нет, вы не можете использовать шаблон обратного вызова, как вам, вероятно, хотелось бы.

Единственное решение-отправить сообщение обратно в основной поток точно так же , как вы это сделали postMessage , и основной поток должен подтвердить это сообщение с message помощью прослушивателя событий и выполнить doSomething функцию самостоятельно.

Ответ №2:

Это немного банально, но в зависимости от вашего варианта использования вы можете сделать что-то вроде следующего:

 // 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)
}
 

Обратите внимание, что eval этого, как правило, лучше избегать, но здесь это может быть безопасно, пока doSomething есть надежный код.

Обратите также внимание, что это не сработает, если doSomething будет зависеть от внешних по отношению к себе зависимостей; все такие зависимости должны быть сериализуемыми и передаваться явно в качестве параметров с помощью одного и того же postMessage механизма.

Комментарии:

1. Я попытался сделать это в своем примере, и произошла такая ошибка : eval(….) не является функцией

2. @BrunoLeo, я виноват, ему нужны скобки, чтобы работать как с объявлениями функций, так и с выражениями функций. Я отредактировал ответ