2016-07-22 16 views
6

私は非常に奇妙な振る舞いを見つけたときにWebワーカーに対処しようとしています。何らかの理由で、実行中のコードがあるにもかかわらず、数秒後に終了します。Webワーカーはなぜ終了しましたか?

ここに私のコードです。

メインのJavaScriptファイル:

$(document).ready(function() { 
    var worker = new Worker("js/TestWorker.js"); 
    worker.addEventListener('message', function (event) { 
     console.log(event.data); 
    }); 

    worker.addEventListener('error', function (event) { 
     console.log(event); 
    }); 
}); 

ワーカーファイル:

(function() { 
    var updateCounter = 0; 

    var updater = function() { 
     updateCounter += 1; 
     console.log("Update counter: " + updateCounter); 

     postMessage("test"); 
     setTimeout(updater, 10000); 
    }; 

    updater(); 
})(); 

述べたように、労働者はわずか数秒、10-20secondsかそこら後に機能を停止します。

しかし、このコードをメインのJavaScriptファイルに追加すると、

var check = function() { 
    var localWorker = worker; 
    // setTimeout(check, 1000); 
}; 

// setTimeout(check, 1000); 

ワーカーは意図したとおりに動作します。 setTimeout-callsも必要ではないので、なぜコメントアウトされていますか? (私はちょうどaswell worker.lengthまたは類似のもので割り当てを置き換えることができますし、それはまだうまく動作することに注意してください。

誰かがこの動作を説明することはできますか?従業員が終了しつつあると(誤って)によってガベージコレクト?。ブラウザまたは何か他のものは、私が欠けている価値が注意することが

は私のブラウザ(クローム)のいずれかのコンソールにエラーや警告をoutputingされていないことであることをここで起こっている

EDIT:コードが無名関数内で実行されるかどうかにかかわらず、同じ動作が観察される。

EDIT2:ワーカー変数をグローバルスコープに配置すると、途中で終了することはありません。この理由は何でしょうか?

+0

非常に好奇心。私は、WebワーカーがDOMノードと似ているという印象を受けました。これは、明示的にのみ殺すことができるということです(つまり、いくつかのリスナーを追加したため、範囲外/ガベージコレクションを外してはいけません)。 FireFoxなどで同じコードを試しましたか?私にはバグのように聞こえる。 – Dave

+0

@Dave Yeah、ちょうどFirefoxでテストされています。 – jimka

答えて

2

グローバルでなければならないいくつかの研究では、ウェブの労働者は、あなたが(すなわち知覚ごみ収集されません)期待として機能するようになっている一方で、どのChromeのいくつかの既知の問題があることを示していますあなたがその行動に頼ることができないことを意味します。 (中によるごみはおそらく任意の今後の活動を行うことができない労働者を収集しようとしhttps://bugs.chromium.org/p/chromium/issues/detail?id=572226

あると思われる。今度はもっと根本的なバグを参照https://bugs.chromium.org/p/chromium/issues/detail?id=572225:特定の関心の

は、この非常によく似たバグだろうこの場合、ガベージコレクションは検出されませんが)、この状態を検出するためのロジックの欠陥は、着信メッセージに応答することに直接関係しない未処理のアクティビティがすべて無視されることを意味します。

基本的に、Webワーカーは明示的にしか削除できないDOMノードのように振る舞いますが、実際には(現時点では)常にワーカーからのアクセスが可能であることを確認する必要がありますそれ以外の場合は、ガベージコレクタがその中で蹴ったときに作業者を殺す可能性があります。これは、作業者でsetTimeoutなどを使用している場合にのみ必要です。メッセージに応答するだけであれば問題はありません。

+0

Ah 、私は見て、興味深い! – jimka

0
(function() { 
... 
})(); 

これは定義後に1回呼び出される無名関数であり、その後はブラウザがそれを破棄します。 あなたのウェブワーカーはそのスコープと定義されているため、短時間しか働かない理由です。

+0

いいえ、それはできません。コードがグローバルスコープで実行される場合、私は同じ動作をします。 – jimka

2

たぶんワーカーvarが

var worker; 

$(document).ready(function() { 
    worker = new Worker("js/TestWorker.js");  
    worker.addEventListener('message', function (event) { 
      console.log(event.data); 
    }); 

    worker.addEventListener('error', function (event) { 
     console.log(event); 
    }); 
}); 
+0

ええ、これに何かがあるようです。変数をグローバルスコープに配置すると、ワーカーは残っています。これはなぜですか? – jimka

+0

私は、ワーカー変数が他の変数と同様にガベージコレクションされていると思います。匿名関数が終了すると、すべてのローカル変数がガベージコレクションされます。 –

+0

ええ、そうですね。それが事実ならば、私はこの問題をより多くの機会に遭遇してしまいました。変数が消えて値が失われました。 – jimka

関連する問題