如何使用 Web Worker 寻找交集?
How to use Web Workers for finding intersection?
我正在尝试使用 Web Worker,但效果不佳。
我的实现不起作用,因为它在任何方面都不 return 为真,因为我认为结果总是假的。当我找到第一个路口时,我应该如何阻止所有工人?
而且所有工人都工作很长时间,
这是我的代码
// 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;
}
}
};
这里当你进行函数调用时,你会经历,创建你所有的工人,然后在最后 return false。不管你的函数是什么,总是return false。
您似乎误解了 Javacript 的异步工作流程。
var handler = function(e){
if(e.data.result){
result = true;
}
}
在主函数已经 return 为 false 之前,上面的函数不会执行。这是作为 onmessage 事件传递的,但它不是同步的,因此您不能修改 'result' 和 return。
一个更好的方法是有一个单独的函数,一旦其中一个工作人员完成,你就会调用它来执行你想在某事完成后执行的操作,或者将回调函数传递给 运行 一次一名工人完成。
您的函数目前是这样工作的:
杀死任何正在工作的工人
this.workers.forEach(function(worker, i){
worker.terminate()
});
this.workers = [];
将结果设为假
var result = false;
对于每个点:检查 Result(此时始终为 false)启动 4 个 worker,并传入一个回调函数,当其中一个完成时,将结果设置为 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 ...
Return 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/
我正在尝试使用 Web Worker,但效果不佳。 我的实现不起作用,因为它在任何方面都不 return 为真,因为我认为结果总是假的。当我找到第一个路口时,我应该如何阻止所有工人? 而且所有工人都工作很长时间,
这是我的代码
// 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;
}
}
};
这里当你进行函数调用时,你会经历,创建你所有的工人,然后在最后 return false。不管你的函数是什么,总是return false。
您似乎误解了 Javacript 的异步工作流程。
var handler = function(e){
if(e.data.result){
result = true;
}
}
在主函数已经 return 为 false 之前,上面的函数不会执行。这是作为 onmessage 事件传递的,但它不是同步的,因此您不能修改 'result' 和 return。
一个更好的方法是有一个单独的函数,一旦其中一个工作人员完成,你就会调用它来执行你想在某事完成后执行的操作,或者将回调函数传递给 运行 一次一名工人完成。
您的函数目前是这样工作的:
杀死任何正在工作的工人
this.workers.forEach(function(worker, i){ worker.terminate() }); this.workers = [];
将结果设为假
var result = false;
对于每个点:检查 Result(此时始终为 false)启动 4 个 worker,并传入一个回调函数,当其中一个完成时,将结果设置为 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 ...
Return 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/