Javascript专用Web工作者按需发送消息

Arn*_*501 5 javascript html5 web-worker

是否可以编写一个简单的专用Web工作程序,以便它连续处理某些内容并仅在客户端请求时发送其状态.

我到目前为止所做的客户文件:

<script>
    // spawn a worker
    var worker = new Worker('basic-worker.js');
    // decide what to do when the worker sends us a message
    worker.onmessage = function(e){
        document.getElementById('result').textContent = e.data;
    };
</script>
<html>
<head></head>
<body>
    <p>The Highest prime number discovered so far : <outpout id="result"></output></p>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

工人档案:

var n = 0;
search: while (true) {
    n += 1;
    for (var i = 2; i <= Math.sqrt(n); i += 1)
        if (n % i == 0)
        continue search;
    // found a prime !
    postMessage(n);
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的那样,工人不断发送它所发现的素数.我希望能够启动主要计算并要求工作人员在我单击客户端上的按钮时发送他创建的最新素数.这就像是(我知道它不能起作用,但能够大致了解我想要的东西):

工人档案:

var n = 0;
var lPrime = 0;
// post last prime number when receiving a message
onmessage = function(e) {
    postMessage(lPrime);
}
// continously search for prime numbers
search: while (true) {
    n += 1;
    for (var i = 2; i <= Math.sqrt(n); i += 1)
        if (n % i == 0)
        continue search;
    // found a prime !
    //postMessage(n);
    lPrime = n;
}
Run Code Online (Sandbox Code Playgroud)

客户档案:

<script>
    // spawn a worker 
    var worker = new Worker('basic-worker.js');
    // what to do when the worker sends us a message
    worker.onmessage = function(e){
        document.getElementById('result').textContent = e.data;
    };
    // post to the worker so the worker sends us the latest prime found
    function askPrime(){
        worker.postMessage();
    };
</script>
<html>
<head></head>
<body>
    <p>The Highest prime number discovered so far : <outpout id="result"></output></p>
    <input type="button" onclick="askPrime();">
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

aps*_*ers 8

这不是一个好的模式.工人是单线程的,因此在任何特定时刻,他们都可以:

  1. 进行计算,

  2. 发送一个事件,或

  3. 回应一个事件.

当您的工作人员正在计算时,它无法响应事件.当您发送最新质数的请求时,您必须等待工作人员完成其正在执行的操作,然后才能处理您的请求.当然,您可以使用setTimeout(或其他方法)允许浏览器"中断"当前的工作(请参阅Javascript - 如何避免在繁重的工作时阻止浏览器?),但工作者的全部意义是拯救您诉诸这种不必要的复杂性.

一个更好的模式是一个非工作变量,它保存最新的素数,并在工人找到新的素数时由工人更新.您可以在需要最新质数时查询该变量,并且您永远不需要等待工作人员处理您的请求.

// spawn a worker 
var worker = new Worker('basic-worker.js');

// store the latest prime as it is produced
var latestPrime = 1;
worker.onmessage = function(e){
    latestPrime = e.data;
};

// fetch the latest prime from the variable
function askPrime(){
    document.getElementById('result').textContent = latestPrime;
};
Run Code Online (Sandbox Code Playgroud)

你也可以通过让两个工人完成这个模式:

  1. 主脚本产生一个拥有最新已知素数的工人.

  2. 该工人产生了第二个工人,该工人实际上完成了工作,并在发现第一个工人时报告新的工件.

这样,第一个工作人员不做任何工作,并且总是可以自由地响应最新的素数,而第二个工作人员永远不需要停止其计算来响应请求.