-4

質問の本質

私がこの質問をする本当の理由は、問題を解決したいからではありません。JavaScript でタスクを操作する方法を知りたいです。スレッドの並列化などは必要ありません。計算処理には、IO と CPU の 2 つの部分があります。私は、送信された ajax リクエストと ajax リクエストがサーバーから応答を取得する間に CPU コンピューティングを動作させたいと考えています。障害があります: 1 つの関数から多くのタスクを実行します。この関数は、実行されたすべてのタスクを待機し、それらの結果を処理し、何らかの値を返す Task を生成する必要があります。それだけです。もちろん、私の問題を解決する別の方法を投稿した場合、私はあなたの回答に投票し、タスクに関する他の回答がない場合は解決策として設定できます。

タスクについて質問するだけでなく、自分の問題を説明するのはなぜですか? 少し前にこの質問を差し引いて閉じた人に聞いてください。

問題

私の問題: JavaScript でツリーをトラバースして、可能な限り最小の解析を見つけたいと考えています。triの形式で保存された単語の辞書があります。ユーザーが入力文字列を指定すると、入力文字列に一致し、単語の組み合わせが最も短い単語の数を取得する必要があります。

例:

  1. 私の辞書には次の単語があります。my, code, js, myj, scode
  2. ユーザータイプmyjscode
  3. 単語の木をたどると、入力が一致myj + scodeし、my + js + code
  4. 最初の解析が最短なので、関数は 2 (最短の解析での単語数) を返します。

私の問題

ディクショナリ ツリーが巨大なため、完全に読み込めません。これを修正するために、遅延読み込みを行いたいと思います。ツリーの各ノードは、ロードされて子ノードを指すか、まだロードされておらず、ロードされるデータへのリンクが含まれています。

そのため、ツリーをトラバースしている間にノード ルックアップ呼び出しを行う必要があります。これらの呼び出しは非同期であるため、ツリー ノードの読み込み中に他のトラバーサルを探索できるようにしたいと考えています。これにより、ユーザーの応答時間が改善されます。

この問題をどのように解決したいですか:

私のルックアップ関数はタスクを返します。そのタスクを呼び出して、その結果を取得できます。ロードされたノードにトラバースすると、子ノードをロードするために複数の呼び出しを行うことができ、各呼び出しはタスクを返します。これらの「タスク」は機能の個々のビットであるため、ajax 呼び出しが返されるのを待っている間に、それらをキューに入れて実行することができます。

ですから、どのライブラリを使用できるか、または JavaScript でタスクをエミュレートする方法を知りたいです (C# に存在するタスクを考えています)。

制限があります。サーバー側のコードはなく、javascript でプリコンパイルされた辞書への ajax のみです。なんで?パスワード複雑度チェッカーとして使用する必要があります。

4

2 に答える 2

2

あなたは質問でこう言います:

もちろん、私の問題を解決する別の方法を投稿した場合、私はあなたの回答に投票し、タスクに関する他の回答がない場合は解決策として設定できます。

良い; 申し訳ありませんが、ここでは C# スタイルのタスクが適切なソリューションではないと思います。

セキュリティ上の理由から、クライアント側ですべてを行う必要があるというあなたの主張を受け入れます (正しいとは思いませんが)。余談ですが、誰かがのぞき見するのが怖い場合 (セキュリティ上の弱点があるため)、パスワードの一部に対して多くのリクエストを渡すことは、1 つのリクエストを渡すことと同じくらい安全ではないことを指摘しておきます。申し訳ありませんが、私は同意なしにそうしたようです!

それにもかかわらず、実際にJavaScriptでそれをしなければならなかった場合、私はあなたの問題にどのようにアプローチするかという大まかな概要で答えようとします。私は約束を使用します。具体的には、おそらく jQuery の Deferred 実装です。ここでは、非常に大まかな疑似コードの概要を示します。

概要

きちんと構造化された Trie から始めます。再帰を使用して、うまく構造化された「ソリューション ツリー」を構築します。これは、ネストされた配列の配列になります。これにより、特定のメッセージでユーザーに応答できる柔軟性が得られます...ただし、そのボーナスを失う準備ができているようで、解決策として 1 桁だけが必要な場合は、少し簡単なアプローチの概要を説明します。 、必要に応じて、次の形式の配列を返すように適応します(例から):

[["myj"],["scode"],["my"],["js"],["code"]]

ここでもこの構造について言及しますが、それは私が採用しているアプローチを説明するのに役立つからです。

ノート

Trie の「nodes」と「valueNodes」を参照します。「ノード」は何でも、「valueNodes」は値を持つノードであると考えています。

再帰的な promiseToResolveRemainder は、「できませんでした」の 0 を解決します。何か問題が発生した場合 (たとえば、Web サービスが利用できなかった場合) にのみ、promise を拒否します。

危険でハックな、テストされていない疑似コード

var minDepth=0; //Zero value represents failure to match (Impossible?  Not if you are accepting unicode passwords!)

function promiseToResolveRemainder(remainder,fragmentSoFar){
    deferred = new jQuery.Deferred();
    nextChar = remainder.substring(0,1);
    if (remainder.length==1){
      //Insert code here to:
      //Test for fragmentSoFar+nextChar being a valueNode.
      //If so, resolve(1)... otherwise resolve(0)
      //!!Note that, subtly, this catches the case where fragmentSoFar is an empty string :)
      return;
    }
    remainder = remainder.substring(1);
    promiseToFindValueNode(fragmentSoFar+nextChar).then(
       function(success){
           //We know that we *could* terminate the growing fragment here and proceed
           //But we could also proceed from here by adding to the fragment
           var firstPathResolvedIn = 0;
           var secondPathResolvedIn = 0;
           promiseToResolveRemainder(remainder,'').then(
               function(resolvedIn){
                   firstPathResolvedIn = resolvedIn + 1;
               }
           ).then(
               promiseToResolveRemainder(remainder,fragmentSoFar+nextChar).then(
                   function(resolvedIn){
                       secondPathResolvedIn = resolvedIn;
                       if(!firstPathResolvedIn==0 and !secondPathResolvedIn==0){
                           deffered.resolve(Math.min(firstPathResolvedIn,secondPathResolvedIn));
                       }
                       deferred.resolve(Math.max(firstPathResolvedIn,secondPathResolvedIn));//Sloppy, but promises cannot be resolved twice, so no sweat (I know, that's a *dirty* trick!)
                   }
               )
           )
       },
       function(failure){
           //We know that we *need* at least a node or this call to
           //promiseToResolveRemainder at this iteration has been a failure.
           promiseToFindNode(fragmentSoFar+nextChar).then(
               function(resolvedIn){
                   //ok, so we *could* proceed from here by adding to the fragment
                   promiseToResolveRemainder(remainder,fragmentSoFar+nextChar).then(
                       function(resolvedIn){
                           deferred.resolve(resolvedIn);
                       }
                   )
               },
               function(failedBecause){
                   //ooops!  We've hit a dead end, we can't complete from here.
                   deferred.resolve(0);
               }
           )
       },
    )
    return deferred.Promise();
}

私は、コードに対するこの未熟な試みを特に誇りに思っているわけではありません (そして、私はあなたのためにあなたのソリューションを書くつもりはありません!) が、私はそのアプローチを誇りに思っており、それが堅牢で信頼性が高く、効率的なソリューションを生み出すと確信しています.あなたの問題。残念ながら、あなたは多くの webService 呼び出しに依存しているようです... したがって、 webServiceへの呼び出しを抽象化し、最初にローカルキャッシュを介してそれらをチェックしたくなるでしょう。

于 2013-07-17T15:47:43.283 に答える
0

これがあなたが探しているものかどうかはわかりませんが、WebWorkers を試すことができます。

簡単な例はhttps://github.com/afshinm/50kにありますが、Google でさらに詳しく調べることができます。

注 - Web ワーカーはブラウザに大きく依存し、マシン上の別のタスクでは実行されません。

于 2013-07-16T02:28:22.733 に答える