1

Worker無期限にループする必要がある in javascript を作成しました。ループ内では、いくつかの非同期呼び出しを行い、それらが完了するのを待ってから続行する必要があります。

これを行うには 2 つの直接的な方法がありますが、どちらも致命的な欠陥があるように思われます。

1)

while(true) {
  var promise = async_call();
  while(!promise.isResolved()) { }
}

2)

var func = function() {
  var promise = async_call();
  promise.done(func);
}
func();

while#1 の場合、内側のループが大量の CPU を消費する可能性があるため、バラバラになります。スレッドが中断可能でない場合 (javascript スレッドは中断可能ですか?私はそうは思いません)、async_call実際に完了する機会が得られないため、ループに陥ってしまいます。

#2については、テールコールの最適化があればうまくいきますが、これを採用しているJavaScript実装はないと思うので、スタックオーバーフローやその他の再帰制限がすぐに発生します.

最後に、終了する必要があるときに両方のループに通知する方法が必要です。これは、ブール変数をコードに入れることで簡単に実行できますが、これstopもワーカー スレッドが割り込み可能であることに依存しているため、stoptrue に設定できます。

私が見落としていたり​​、見慣れていないデザイン パターンはありますか? setIntervalpolling と組み合わせたようなものに頼らずに、ワーカーをできるだけ速く実行するにはどうすればよいisResolvedですか?

4

2 に答える 2

3

パターン 2 は問題ありません。イベントは完全に新しいスタックで実行されるため、コールバックが実際に非同期である場合 (一部の Promise ライブラリはそれを強制します)、スタック オーバーフローに陥ることはありません。同期的に呼び出す 場合にのみfunc、オーバーフローが発生しますが、コールバックとして同期的に登録するだけです。

于 2012-12-17T16:39:33.277 に答える
0

async_callが XHR リクエストまたはコールバックであると仮定するとsetTimeout、スタックがオーバーフローすることはありません。イベント コールバック (XHR 完了など) は新しいスタックで呼び出されます。それは実際には再帰ではありません。

ワーカーに停止するように通知する限り、メッセージ パッシングを使用します。

var worker = new Worker('worker.js');
// when you need to stop it:
worker.postMessage('stop');

worker.js

onmessage = function(e) {
    if (e.data == 'stop') {
        // stop
    }
}
于 2012-12-17T16:39:01.600 に答える