2016-07-21 19 views
0

私は日々のオンライン商取引の中で企業を支援するためにクローズドシステムWebアプリケーションに取り組んでいます。つまり、一方では一般に公開されず、流暢な仕事経験を維持しながら大量のデータを処理する必要があります。2人のJSウェブワーカーの同時実行:1人がスタックする

これは、私がJSのWebワーカーに目を向けて、あらゆる種類のデータベースアクセスとデータ読み込みをバックグラウンドで実行する理由です。 私の理解は、メインのUI /メインJSが中断されずにいるだけでなく、異なるWebワーカーが互いに干渉することなく動作することです。

私は今、次のセットアップを持っている:

mainJS:pageload上で動作する機能statusCheck:労働者である

function statusCheck() { 
    if(typeof(w__statusCheck) == "undefined") { 
     var w__statusCheck = new Worker("...statusCheck.js"); 
     w__statusCheck.postMessage("go"); 
     w__statusCheck.onmessage = function(e) { 
      var message = JSON.parse(e.data); 
      if(message.text!=undefined) displayMessage(message.text); 
     } 
} 

statusCheck.jsは、単純にこのように書きます:

function checkStatus() { 
     console.log("statusCheck started"); 
     // I will leave standard parts out: 
      // creating and testing the ajax variable against different browsers 

     ajaxRequest.onreadystatechange = function() { 
      if(ajaxRequest.readyState == 4) { 
       self.postMessage(ajaxRequest.responseText); 

       var timer; 
       timer = self.setTimeout(function(){ 
        checkStatus(); 
       }, 1000); 
      } 
     } 

     ajaxRequest.open("GET", "...worker_statusCheck.php", true); 
     ajaxRequest.send(null); 
    } 

    this.onmessage = function(e){ 
     checkStatus(); 
    }; 

ご覧のとおり、これは毎秒それ自身を再起動します。インターヴォールは生産が長くなるかもしれません。 worker_statusCheck.phpは、単にデータベースとは異なるものを取得し、それらをJSONオブジェクトに編成して、私にシステムステータスを与えます。

これは美しく機能します。

今、私は効果的にアクションを実行するために、いくつかのPHPを呼び出すためのリンクをクリックすることにより開始を取得することになっている別のワーカーがあります。特定のリンク上でこれをすべてのクリックで mainJS loadWorker

function loadWorker(url="") { 
    console.log("loadWorker started"); 

    if(url!="") { 
     var uniqueID = "XXX" // creating a random ID based on timestamp and Math.random() 

    if(typeof(window[uniqueID]) == "undefined") { 
     var variables = { ajaxURL: url }; 
     window[uniqueID] = new Worker("....loadWorker.js"); 
     window[uniqueID].postMessage(JSON.stringify(variables)); 
     window[uniqueID].onmessage = function(e) { 
      var message = JSON.parse(e.data); 
      if(message["success"]!=undefined) { 
       variables["close"] = "yes"; 
       window[uniqueID].postMessage(JSON.stringify(variables)); 
      } 
     } 
} 

を一意の名前のワーカーを作成し、実行し、データを受け取り、ワーカーにclose()と伝えます。

PHPはまた、その事を行い、長い手順の各ステップの後に進捗状況の更新をDBに書き込みます。これらの進捗状況の更新は、上記の繰り返しステータスチェックでDBから取得します。

ここで、タイムスタンプ付きのDBのエントリを見ることができるので、それぞれの時間に書き込まれることが分かります。 したがって、両方の作業者が仕事をして確実に実行されます。しかし私は、手動(無作為に指定された)作業者を開始するたびに、statusCheckは実際に実行を停止することに気付きました。それはちょうど立ち往生する...私は両方の労働者からのコンソールの出力でこれを確認することができた。したがって、スタックされているようなメインJSではなく、statusCheckは実際には一時停止し、loadWorkerが完了すると再開します。

ここでは何か基本的なものがありませんか?私がこのウェブワーカーのコンセプトに慣れて以来、どんな洞察も高く評価されます。

ありがとう:)

答えて

-1

いいえ..わかりました: 私はすべての間違った場所を探していました。私は、ワーカーが呼び出すすべてのPHPスクリプトでPHPセッションを初期化しました。そして私の2人の平行労働者はどちらも1人と呼ばれました。したがって、セッションファイルは最初のPHPスクリプトによってロックされ、2番目のスクリプトは再び開くまで待たなければなりませんでした。それは労働者やJSが妨げられていない、それはPHPだった。

私はstatusCheck.phpからセッション初期化を取り出しました。これは魅力的です。ユーザー入力応答を処理する他のユーザーには、作業者が実行する「コンパイルデータXY」ボタンをクリックしてしばらく時間がかかりますので、実際にそれが意味をなされているので、それを保持します。彼はすでに次のボタン「このデータを表示」をクリックしています。セッションファイルがロックされているため、これらのアクションのためのきれいなキューがあります。 :)

私はまだ上記の推奨事項を念頭に置いて、コードを改善するために参照してください。 :)

+0

これは、最初からコンソールで簡単に見ることができるものです... –

+0

そうですか?どうやって?私はJSと文書メッセージしか見ることができません。 PHPの出力はありません。また、どこにもエラーはありませんでした。ただの遅れ。たぶん私はあなたのように啓発されていないので、おそらくここで私を助けることができます... –

+0

コンソールを調べると、要求の1つがロードされていて、データを受信して​​いないことがわかります。それはあなたがサーバーとの通信に問題があることを知るのに十分なヒントを与えてくれるでしょうし、Webワーカーに関連していないことを簡単にチェックできます。あなたはまだ問題が何であるか把握する必要がありますが、少なくともクリスタルボールなしでは答えられない質問は投稿しません。また、「*あなたのように悟りがないかもしれない」という言葉は、失礼な風刺として頻繁に使用されるので、熱い議論を避けるためにインターネット上で避けるほうが良いです。 –

0

あなたの質問は本当に正確に間違って行くかを把握するためのリソースが不足しています。私はtwo web workers can operate at the same timeと同時に同期操作で同意することができます。私はforループと同期XHR要求の両方についてこれをテストしました。

私は何とかお勧めします。

最初に - CPUの重いアルゴリズムでデータを処理しない限り、Webワーカーは時間の無駄です。 XHRリクエストはメインスレッドをブロックしません(明示的に要求しない限り)。

  1. statusCheck()には、var w__statusCheckというローカル変数を宣言しています。したがって、外部スコープから見て常にnullになります。コードがワーカーで実行されていなければ、ガベージコレクションされる可能性があります。
  2. XMLHttpRequest.onreadystatechangeを使用しないでください。 onloadonerrorを使用してください。
  3. 変数のためのランダムな一意のIDはほとんど常に間違っています。ワーキングレフェレンスをまったく保存する必要がある場合は、合理的な名前(たとえば、ロードするURL)を付けたり、インクリメンタルIDを使用したりしてください。
  4. Do NOTstringifyウェブワーカーに投稿するデータ。おそらくより最適な方法で、ブラウザによって既に完了しています。データを何かに変換することは、人々がWebワーカーを使って行う最も一般的なばかげたことです。

質問を投稿するときにも、少なくともコードが意味をなさないことを確認してください。あなたのポストでは中括弧は一致しません。

+0

まずは:ポインタのおかげで!私はそれらを見て、それらを試して、それがどこにつながるのか見てみましょう。 ウェブワーカーをまったく使用しているかどうかについては、アプリの最初のバージョンは数年前から使用されており、最初のアイデアの後にますます多くの機能が利用されています。これまでに、実際には重くて長い計算が実行されています。 欠けている括弧について:私は作業コードからコピーし、ここでエディタで無関係な部分を取り除きました。私はあまりにも多くを持っていると思います。 私はすべてを試し、ここに結果を投稿します。良い週末を!! –

+0

はランダムIDについて尋ねることを意図していました。彼らがほとんど常に間違っている論理的な理由はありますか?私の目標は、それらをすべてユニークにして何も干渉しないことでした。とにかく実行の直後にクローズ()されているので、他のコンテキストで知られる必要はありません... var名には特別な文字はありませんか?だから、私はこのような名前を作成します: '' WorkerID _ "+ random_number + now()' –

+0

@AurelEngleEngelmann私は、インクリメント(例えば0,1,2,3)の代わりに乱数を使用することは論理的ではないと考えています。これは、作成順序についての情報を提供するので、デバッグも簡単です。乱数を作成する方法は、あなたがよりよく混在するランダムなものがより良くなると思うように見えますが、それは真実ではありません。そして、変数名は特殊文字を持つことはできません。しかし、オブジェクトのプロパティは可能です。これは有効です: 'var dd = {"☺ ":" smiley "}'これもそうです: 'window ["☺ "] =" smiley "' –

関連する問題