5

シンプルな専用 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>

ワーカー ファイル:

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

これは良くないパターンです。ワーカーはシングルスレッドであるため、いつでも次のいずれかを実行できます。

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

2 つのワーカーを使用して、このパターンを実現することもできます。

  1. メイン スクリプトは、最新の既知の素数を保持するワーカーを生成します。

  2. そのワーカーは、実際に作業を行う 2 番目のワーカーを生成し、発見された新しい素数を最初のワーカーに報告します。

そうすれば、最初のワーカーは何もせず、いつでも自由に最新の素数で応答できます。2 番目のワーカーは、リクエストに応答するために計算を停止する必要はありません。

于 2013-06-17T12:45:22.467 に答える