有没有办法在一个文件中有不同的工作函数
Is there a way to have different worker functions in one file
阅读有关 web workers 的文章时,我从 mdn 中偶然发现了这个 example。 worker.js
只是一个简单的函数。
因此,当我们 post 向工作人员发送消息时, onmessage
部分将由工作人员启动。在这个简单的例子中,工作人员只是将两个数字相乘。但是,如果我想要一个可以加、除等的 worker 怎么办?我是否需要为我希望我的工作人员 运行 的每个功能创建一个新的工作人员文件(例如 worker_add.js
)?或者更简洁的处理方法是什么?
我正在考虑将字符串 posted 作为工作程序的第一个参数
myWorker.postMessage(["method", arg1, arg2]);
然后在我的 worker 中我有 if/else
条件判断字符串是否匹配然后执行不同的代码。
importScripts('emscripten.js')
onmessage = function(e) {
console.log('Message received from main script.');
if (e.data[0] == "method1")
{
Module.method1(e.data[1].byteOffset, e.data[2]);
postMessage(e.data[1]);
}
else if (e.data[0] == "method2")
{
var ret= Module.method2();
postMessage(ret);
}
console.log('Posting message back to main script');
}
除了在消息本身中传递一些元数据之外,我认为没有更好的方法来做你想做的事情。
但是您的实施可以很容易地改进。而不是切换器,只是始终将第一个参数视为函数名,所有其他参数都是此函数的参数,函数结果直接 post 返回:
onmessage = function(e) {
postMessage(Module[e.data[0]].apply(Module, e.data.slice(1)));
}
简单的一行,它关心你的 worker 中的任意数量的函数。
如果辅助函数结果是异步的,您可以检查函数结果是否为例如Promise
和 post 承诺的消息 resolve
而不是直接 post 发送消息。
由于您可以通过字符串化 AJAX,您可以轻松地在您的 worker 中实现条件逻辑。
只需传递一个参数来告诉工作人员要做什么:
//This snippet won't run, it's just to illustrate
//main.js
var worker = new Worker('/js/worker.js');
worker.addEventListener("message", function(event) {
if (event.data["do"] == "main") {
console.log("One task complete");
} else if (event.data["do"] == "second") {
console.log("Other task complete");
}
}, false);
function doMainTask(taskParam) {
worker
.postMessage({
taskParam: JSON.stringify(taskParam),
"do": "main"
});
}
function doSecondTask(taskParam) {
worker
.postMessage({
taskParam: JSON.stringify(taskParam),
"do": "second"
});
}
//worker.js
function messageHandler(event) {
var obj = JSON.parse(event.data);
var str = "";
if (obj["do"] == "main") {
str = main(obj.taskParam);
} else if (obj["do"] == "second") {
str = second(obj.taskParam);
}
this.postMessage({
msg: str,
"do": obj["do"],
obj: obj
});
}
this.addEventListener('message', messageHandler, false);
function main(taskParam) {
return "main";
}
function second(taskParam) {
return "second";
}
本着 Emil 回答的精神,我在 html5rocks 上找到了一个例子。我觉得这比 Emil 的回答稍微干净一些。
主要脚本如下所示
<button onclick="sayHI()">Say HI</button>
<button onclick="unknownCmd()">Send unknown command</button>
<button onclick="stop()">Stop worker</button>
<output id="result"></output>
<script>
function sayHI() {
worker.postMessage({'cmd': 'start', 'msg': 'Hi'});
}
function stop() {
// worker.terminate() from this script would also stop the worker.
worker.postMessage({'cmd': 'stop', 'msg': 'Bye'});
}
function unknownCmd() {
worker.postMessage({'cmd': 'foobard', 'msg': '???'});
}
var worker = new Worker('doWork2.js');
worker.addEventListener('message', function(e) {
document.getElementById('result').textContent = e.data;
}, false);
</script>
和工人 doWork2.js
是这样的:
self.addEventListener('message', function(e) {
var data = e.data;
switch (data.cmd) {
case 'start':
self.postMessage('WORKER STARTED: ' + data.msg);
break;
case 'stop':
self.postMessage('WORKER STOPPED: ' + data.msg +
'. (buttons will no longer work)');
self.close(); // Terminates the worker.
break;
default:
self.postMessage('Unknown command: ' + data.msg);
};
}, false);
阅读有关 web workers 的文章时,我从 mdn 中偶然发现了这个 example。 worker.js
只是一个简单的函数。
因此,当我们 post 向工作人员发送消息时, onmessage
部分将由工作人员启动。在这个简单的例子中,工作人员只是将两个数字相乘。但是,如果我想要一个可以加、除等的 worker 怎么办?我是否需要为我希望我的工作人员 运行 的每个功能创建一个新的工作人员文件(例如 worker_add.js
)?或者更简洁的处理方法是什么?
我正在考虑将字符串 posted 作为工作程序的第一个参数
myWorker.postMessage(["method", arg1, arg2]);
然后在我的 worker 中我有 if/else
条件判断字符串是否匹配然后执行不同的代码。
importScripts('emscripten.js')
onmessage = function(e) {
console.log('Message received from main script.');
if (e.data[0] == "method1")
{
Module.method1(e.data[1].byteOffset, e.data[2]);
postMessage(e.data[1]);
}
else if (e.data[0] == "method2")
{
var ret= Module.method2();
postMessage(ret);
}
console.log('Posting message back to main script');
}
除了在消息本身中传递一些元数据之外,我认为没有更好的方法来做你想做的事情。
但是您的实施可以很容易地改进。而不是切换器,只是始终将第一个参数视为函数名,所有其他参数都是此函数的参数,函数结果直接 post 返回:
onmessage = function(e) {
postMessage(Module[e.data[0]].apply(Module, e.data.slice(1)));
}
简单的一行,它关心你的 worker 中的任意数量的函数。
如果辅助函数结果是异步的,您可以检查函数结果是否为例如Promise
和 post 承诺的消息 resolve
而不是直接 post 发送消息。
由于您可以通过字符串化 AJAX,您可以轻松地在您的 worker 中实现条件逻辑。
只需传递一个参数来告诉工作人员要做什么:
//This snippet won't run, it's just to illustrate
//main.js
var worker = new Worker('/js/worker.js');
worker.addEventListener("message", function(event) {
if (event.data["do"] == "main") {
console.log("One task complete");
} else if (event.data["do"] == "second") {
console.log("Other task complete");
}
}, false);
function doMainTask(taskParam) {
worker
.postMessage({
taskParam: JSON.stringify(taskParam),
"do": "main"
});
}
function doSecondTask(taskParam) {
worker
.postMessage({
taskParam: JSON.stringify(taskParam),
"do": "second"
});
}
//worker.js
function messageHandler(event) {
var obj = JSON.parse(event.data);
var str = "";
if (obj["do"] == "main") {
str = main(obj.taskParam);
} else if (obj["do"] == "second") {
str = second(obj.taskParam);
}
this.postMessage({
msg: str,
"do": obj["do"],
obj: obj
});
}
this.addEventListener('message', messageHandler, false);
function main(taskParam) {
return "main";
}
function second(taskParam) {
return "second";
}
本着 Emil 回答的精神,我在 html5rocks 上找到了一个例子。我觉得这比 Emil 的回答稍微干净一些。
主要脚本如下所示
<button onclick="sayHI()">Say HI</button>
<button onclick="unknownCmd()">Send unknown command</button>
<button onclick="stop()">Stop worker</button>
<output id="result"></output>
<script>
function sayHI() {
worker.postMessage({'cmd': 'start', 'msg': 'Hi'});
}
function stop() {
// worker.terminate() from this script would also stop the worker.
worker.postMessage({'cmd': 'stop', 'msg': 'Bye'});
}
function unknownCmd() {
worker.postMessage({'cmd': 'foobard', 'msg': '???'});
}
var worker = new Worker('doWork2.js');
worker.addEventListener('message', function(e) {
document.getElementById('result').textContent = e.data;
}, false);
</script>
和工人 doWork2.js
是这样的:
self.addEventListener('message', function(e) {
var data = e.data;
switch (data.cmd) {
case 'start':
self.postMessage('WORKER STARTED: ' + data.msg);
break;
case 'stop':
self.postMessage('WORKER STOPPED: ' + data.msg +
'. (buttons will no longer work)');
self.close(); // Terminates the worker.
break;
default:
self.postMessage('Unknown command: ' + data.msg);
};
}, false);