5

是否可以编写一个简单的专用网络工作者,以便它连续处理某些内容并仅在客户端询问时发送其状态。

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

<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>

工人档案:

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);
}

正如你所看到的,工人不断地发送它找到的素数。例如,当我单击客户端上的按钮时,我希望能够启动素数计算并要求工作人员发送他发现的最新素数。那将是这样的(我知道它不能正常工作,只能大致了解我想要什么):

工人档案:

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;
}

客户档案:

<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>
4

1 回答 1

8

这不是一个好的模式。Worker 是单线程的,因此在任何给定时刻,它们都可以:

  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;
};

您还可以通过拥有两个工人来完成此模式:

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

  2. 该工作人员产生第二个工作人员,该工作人员实际完成工作,并在发现新的素数时向第一个工作人员报告。

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

于 2013-06-17T12:45:22.467 回答