#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, я виноват, ему нужны скобки, чтобы работать как с объявлениями функций, так и с выражениями функций. Я отредактировал ответ