7

コンテキスト

  • 大量の構造化データ(ビジネスプロセスモデル)を処理するEmberベースのアプリがあります。
  • 重要!アプリを可能な限りオフラインにできるようにしたいと考えています。

必要なもの

これらのデータを表示したり編集したりするだけで済みますが、レーダーにはショーストッパーはありません...

しかし今、私たちはこれらのモデルに処理を適用したいと思います:妥当性チェック、パス検索...そしていくつかの種類の時間/メモリを消費するアルゴリズム。

問題

サーバー上でアルゴリズムを処理することはできますが、それではアプリのオフラインモードが停止します。

バックグラウンドでアプリケーションとプロセスのアルゴリズムがフリーズしないようにWebワーカーについて考えてきましたが、データをワーカーに渡す際のデータの重複という大きな問題に直面しました。Transferable Objectsを使用すると、少なくとも計算中にアプリの所有権(およびデータ)が失われるため、実行可能ではないようです。

この問題をどのように処理しますか?アルゴリズムの「コルーチンのような」実装を使用する唯一の方法はありますか?どんな手掛かり?

4

2 に答える 2

5

開発した長い JavaScript 処理中に UI をフリーズさせないことが主な関心事である場合は、ループ本体を順次ステップにリファクタリングして、各ステップが を使用して次のステップを呼び出すようにすることができますwindow.setTimeout。この手法により、(単一の) スレッドが各インタラクション間で UI イベントを処理できるようになります。

var pr = function(x) {console.log(x)};
var COUNT=3;

// original regular javascript loop
for(var i=0; i<COUNT; i++) {
  var msg = "current index is (" + i + ")";
  pr(msg);
}

// step-by-step sequential calls
var body = function(i) {
  var msg = "non-blocking for: index is (" + i + ")";
  pr(msg);
}
nonBlockingFor(body, 4);

この関数nonBlockingForは、2 番目の引数として渡された回数だけ、最初の引数を (関数として) 呼び出します。その定義は次のとおりです。

// function constructor
var nonBlockingFor = (function() {
  function _run(context) {
    if(context.idx > context.max) return;
    context.fnc(context.idx++);
    window.setTimeout((function(){ _run(context)}), 1);
  }
  return (function _start(ufn, uqt, runId) {
    _run({idx: 0, max: uqt -1, fnc: ufn || (function(){}), runId: runId});
  });
})();

これは非常に単純化された関数であり、他のマルチスレッド関連の問題を処理するように改善できることに注意してください。つまり、スレッドの終了 (結合) を待機します。このコードがお役に立てば幸いです。問題に対するこのアプローチが気に入ったら、私に知らせてください。よろしければ、私の提案を改善するために時間を費やすことができます。

于 2012-07-04T12:04:05.490 に答える
3

長い時間が経ちましたが、まだ : 解決策はhttp://jscex.info/かもしれません

Javascript は本質的にシングル スレッドであり、マルチスレッドは難しいトピックであるため、これは設計上の選択であり、カジュアルな JavaScript 開発者の 99% は適切に処理できません。

ワーカーは別のスレッドを取得し、UI をブロックしない唯一の方法ですが、実際のマルチスレッドの危険な副作用なしで使用できるようにするために、お気づきのように完全に分離されたコンテキストで実行されます。そのため、別のスレッドを生成するよりも、コマンド ライン パラメータを渡す外部コマンドを呼び出すことに似ています。

したがって、「非同期」モードで作業することが現時点で唯一の解決策ですが、ボタンのクリックやリモート接続が完了するのを待っているわけではないため、バインドできる唯一の非同期イベントはタイマーの目盛りです。 js で長時間実行される操作を悩ませる貧弱なコード スタイルにつながります。

ただし、非常に興味深く、まったく知られていないことがわかった小さなライブラリがあります (ウェブサイトが貧弱であるにもかかわらず) 美しく書かれた手続き型コードをオンザフライでタイマーの混乱に「変換」し、非同期モデルを本質的に機能させることができます必要: http://jscex.info/

Windows 3.1 の場合と同様に、ブラウザが完全にフリーズしないように、しばらくブラウザに "譲る" ( $await(Jscex.Async.sleep(50)); ) 必要があります。実際にはボンネットの下でフリーズしますが、頻繁に譲歩すると誰も気付かないでしょう:)単一の命令セットに取り組んでいる..それを20ミリ秒にすると、誰にもわかりません)。

それは、実際にそのようなコードを「書く」ことなく、コルーチンのような JS を「生成」するのに役立つと思いますが、それを台無しにする作業を「プリコンパイラ」に委任します。

于 2012-10-18T03:13:10.423 に答える