我正在尝试使用Web Workers,但效果并不好。 我的实现不起作用,因为它没有以任何方式返回true,因为我认为结果总是错误的。当我找到第一个十字路口时,我该如何阻止所有工人? 所有工人也都工作很长时间,
这是我的代码
// Delete all workers in previous iteration, because the don't need
this.workers.forEach(function(worker, i){
worker.terminate()
});
this.workers = [];
var result = false;
// For each line in polyline I create 4 workers for finding intersection with rectangle of selection
for(var i=1; i<this.dots.length; ++i){
if(result)
return true;
var handler = function(e){
if(e.data.result){
result = true;
}
};
this.workers.push(new Worker("js/intersection.js"));
this.workers[this.workers.length-1].onmessage = handler;
this.workers[this.workers.length-1].postMessage({type: "line_vs_line", l1p1: first_dot, l1p2: {x: second_dot.x, y: first_dot.y}, l2p1: {x: this.dots[i].dot.x, y: this.dots[i].dot.y}, l2p2: {x: this.dots[i-1].dot.x, y: this.dots[i-1].dot.y}});
this.workers.push(new Worker("js/intersection.js"));
this.workers[this.workers.length-1].onmessage = handler;
this.workers[this.workers.length-1].postMessage({type: "line_vs_line", l1p1: {x: second_dot.x, y: first_dot.y}, l1p2: second_dot, l2p1: {x: this.dots[i].dot.x, y: this.dots[i].dot.y}, l2p2: {x: this.dots[i-1].dot.x, y: this.dots[i-1].dot.y}});
this.workers.push(new Worker("js/intersection.js"));
this.workers[this.workers.length-1].onmessage = handler;
this.workers[this.workers.length-1].postMessage({type: "line_vs_line", l1p1: second_dot, l1p2: {x: first_dot.x, y: second_dot.y}, l2p1: {x: this.dots[i].dot.x, y: this.dots[i].dot.y}, l2p2: {x: this.dots[i-1].dot.x, y: this.dots[i-1].dot.y}});
this.workers.push(new Worker("js/intersection.js"));
this.workers[this.workers.length-1].onmessage = handler;
this.workers[this.workers.length-1].postMessage({type: "line_vs_line", l1p1: {x: first_dot.x, y: second_dot.y}, l1p2: first_dot, l2p1: {x: this.dots[i].dot.x, y: this.dots[i].dot.y}, l2p2: {x: this.dots[i-1].dot.x, y: this.dots[i-1].dot.y}});
}
return false;
该工作人员的代码:
onmessage = function(e){
var l1p1 = e.data.l1p1;
var l1p2 = e.data.l1p2;
var l2p1 = e.data.l2p1;
var l2p2 = e.data.l2p2;
switch(e.data.type){
case "line_vs_line":{
var q = (l1p1.y - l2p1.y) * (l2p2.x - l2p1.x) - (l1p1.x - l2p1.x) * (l2p2.y - l2p1.y);
var d = (l1p2.x - l1p1.x) * (l2p2.y - l2p1.y) - (l1p2.y - l1p1.y) * (l2p2.x - l2p1.x);
if( d == 0 )
postMessage({result: false});
else{
var r = q / d;
q = (l1p1.y - l2p1.y) * (l1p2.x - l1p1.x) - (l1p1.x - l2p1.x) * (l1p2.y - l1p1.y);
var s = q / d;
postMessage({result: !( r < 0 || r > 1 || s < 0 || s > 1 )});
console.log(r,s);
}
break;
}
}
};
答案 0 :(得分:1)
在您进行函数调用时,您将完成所有工作,然后在结尾处返回false。无论你的功能如何,总会返回虚假。
您似乎误解了Javacript的Async工作流程。
var handler = function(e){
if(e.data.result){
result = true;
}
}
在main函数返回false之后,上述函数才会执行。这是作为onmessage事件传递的,但它不是同步的,因此您无法修改结果&#39;并返回。
更好的方法是让一个单独的函数在一个工作完成时调出,一旦完成就完成你想要做的操作,或者在一个工作完成后传入一个回调函数来运行。
您的功能目前的工作原理如下:
杀死所有工作的员工
this.workers.forEach(function(worker, i){
worker.terminate()
});
this.workers = [];
将结果设为假
var result = false;
对于每个点:检查Result(此时始终为false)旋转4个worker,并传入一个回调函数,当其中一个完成时,将result设置为true。
for(var i=1; i<this.dots.length; ++i){
if(result)
return true;
// This will never happen as result is false for all loops at this point.
var handler = function(e){
if(e.data.result){
result = true;
}
};
//Etc, spin up 4 workers ...
返回false(函数退出)
return false;
// This always returns false,
// nothing is stopping the function from getting here.
您的工作人员逐一完成并执行该功能,但是没有设置结果变量(所以它可能将全局变量设置为true)
// Workers now execute this snippet one by one...
// but on the global scope, so result is going to be set globally,
// and not in your function.
if(e.data.result){
result = true;
}
您无法对其执行任何操作,因为此时尚未执行任何其他功能。
这有意义吗?您无法以与同步工作流相同的方式考虑异步工作流。
这是一篇关于异步的文章:http://recurial.com/programming/understanding-callback-functions-in-javascript/