あなたは質問でこう言います:
もちろん、私の問題を解決する別の方法を投稿した場合、私はあなたの回答に投票し、タスクに関する他の回答がない場合は解決策として設定できます。
良い; 申し訳ありませんが、ここでは 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への呼び出しを抽象化し、最初にローカルキャッシュを介してそれらをチェックしたくなるでしょう。