2012-02-25 19 views
0

私の質問は基本的には、Ajaxの汎用機能を解析して情報を取得するためだけにしようとしています。この機能は解析され、呼び出されたものの値として自動的に格納されます。この特定のケースでは、私が作っているハンケマンゲームのための巨大な辞書の単語リストです。 ajaxRequest.responseText.split("\n")によって作成された配列を、どのようなものにでもエスケープできます。私の場合、それはALAMI.Hangman.WordlistXHR関数から解析されたデータをエスケープするにはどうすればよいですか?

私の最終目標は、ALAMI.Hangman.Wordlist[i]を使用して、それがどのような文字列の値を配列にその場所に格納されている返す持ってできるようになっております。

これは私のコードのすべてではありませんが、XHRリクエスト機能はALAMI.XHR();によって呼び出されますが、以下のように呼び出されていますが、このコードには含まれませんでした。

ALAMI.XHR.Get = function(URL){ 
    "use strict"; 
    var ajaxRequest = ALAMI.XHR(); 
    var ajaxResponse; 

    ajaxRequest.open("GET", URL, true); 
    ajaxRequest.send(null); 
    ajaxRequest.onreadystatechange = function(){ 
    if(ajaxRequest.readyState === 4){ 
     ajaxResponse = ajaxRequest.responseText.split("\n"); 
     var extensionLocation = URL.lastIndexOf('.'); 
     console.log(URL.substr(extensionLocation) + " file ...... " + ajaxResponse.length + " lines."); 
    } 
    } 
    return ajaxResponse; 
} 

ALAMI.Hangman = ALAMI.Hangman || {}; 

ALAMI.Hangman.Wordlist = ALAMI.XHR.Get('fulldictionary.txt'); 

//I want ALAMI.Hangman.Wordlist to be equal to the Array of ajaxRequest.responseText.split("\n") 

私の最終目標は、ALAMI.Hangman.Wordlist[i]を使用して、それがアレイ内のその場所に格納されているものは何でも、文字列の値を返す必要がありすることができることです。

また、私はajax関数を普遍的な方法で無限回数使用できるようにしようとしています。

ALAMI.Hangman.Wordlist1 = ALAMI.XHR.Get('fulldictionary.txt'); 
ALAMI.Hangman.Wordlist2 = ALAMI.XHR.Get('dictionary2.txt'); 

が最終目標は次のとおりです:例えば

グローバル空間で、私はconsole.log(ALAMI.Hangman.Wordlist[0]);を記述する場合、それは現在未定義として表示配列がそうALAMI.Hangman.Wordlistに格納されているとのために、しかし、私が欲しいのです私がそれをすると、配列の最初の値が出力されます。 [コメントに基づいて編集した]

console.log(ALAMI.Hangman.Wordlist[0]); //Should output Apple

+0

多くの点:(1)ALAMIとは何ですか? (2) 'fulldictiornay.txt'は私にとって有効なURLのようには見えません(3)' onreadystatechange'関数が別のスレッドで実行されていて、onreadystatechangeの 'ajaxResponse'の値がメインスレッドで利用できないことを知っていますか? 'return ajaxaResponse'は決して動作しませんか? –

+0

ALAMIは、私がjavascriptで作成したすべてのもの(私はYAHOOなどとは対照的に)のための私の個人的な名前空間です。 fulldictionary.txtは.jsファイルとhtmlファイルと同じフォルダにあるため、有効なURLです。このコードのすべては、 'ajaxResponse'の戻り値を除いて動作します。 – person0

答えて

0

私はこの質問にお答えしてくれた皆様に感謝します!質問に答えるのに役立つ有益な関連情報がすべて含まれていましたが、問題を解決するために必要なすべての回答が1つもないため、回答を投稿しています。次のように

解決策は以下のとおりです。

  1. 私はcallback functionを使用する必要がありました。
  2. コールバック関数は、XHR要求が完了した後にのみ実行する必要があります。

    - これは特に重要であり、非同期AJAXを使用していることに関連しています。

  3. ALAMI.Hangman.Wordlistがに等しく設定され、ALAMI.XHR.Get()に設定されていないことを確認する必要がありました。

私が思い描いたコードは次のとおりです。

ALAMI.XHR.Get = function(URL, callback){ //callback argument was added 
    "use strict"; 
    var ajaxRequest = ALAMI.XHR(); 
    var ajaxResponse; 

    ajaxRequest.open("GET", URL, true); 
    ajaxRequest.send(null); 
    ajaxRequest.onreadystatechange = function(){ 
    if(ajaxRequest.readyState === 4){ 
     ajaxResponse = ajaxRequest.responseText.split("\n"); 
     var extensionLocation = URL.lastIndexOf('.'); 
     console.log(URL.substr(extensionLocation) + " file, " + ajaxResponse.length + " lines"); 
     if(callback){ 
     callback(ajaxResponse); //callback is called after URL is parsed into an Array 
     } 
    } 
    } 
} 

ALAMI.Hangman = ALAMI.Hangman || {}; 
ALAMI.Hangman.Wordlist; 

ALAMI.XHR.Get('fulldictionary.txt', function(aR){ //callback function is specified 
    ALAMI.Hangman.Wordlist = aR;     //assigning the Wordlist property now works! 
    console.log('Wordlist Retrieved'); 
}); 
1

あなたはXHRリクエストの結果からALAMI.Hangman.Wordlistを投入したい場合は、その要求

ALAMI.Hangman = ALAMI.Hangman || {}; 

//change ALAMI.XHR.Get = function(URL) to 
//  ALAMI.XHR.Get = function(URL,listID) 

ALAMI.XHR.Get('fulldictionary.txt','WordList'); 
ALAMI.XHR.Get('fulldictionary2.txt','WordList2'); 
ALAMI.XHR.Get('fulldictionary3.txt','WordList3'); 

// [...] 
    ajaxRequest.onreadystatechange = function(){ 
    if(ajaxRequest.readyState === 4){ 
     ajaxResponse = ajaxRequest.responseText.split("\n"); 
     var extensionLocation = URL.lastIndexOf('.'); 
     ALAMI.Hangman[listID] = ajaxResponse; // <=== 
     // [...] 
     // do stuff with the populated ALAMI.Hangman[listID] 
    } 
    } 
のコールバックにそれを行う必要があります
+0

しかし、問題は、私のajax関数を無限回数使用できる普遍的な方法にしようとしていることです。 例: 'Wordlist1 = ALAMI.XHR.Get( 'fulldictionary.txt')' 'Wordlist2 = ALAMI.XHR.Get( 'dictionary2.txt')'私はあなたが提案したことを既に行っていますが、それは満足しません私の最終目標 – person0

+0

編集された回答を参照してください... – KooiInc

+0

さて、それは実際には私の問題を最後に解決しません。私のコード全体で膨大な機能の中で 'ALAMI.Hangman [WordList]'や 'ALAMI.Hangman.WordList'を使い始めるとどうなりますか?私があなたが言及したことをすると、それは未定義として表示され続けますか? – person0

1

したがって、WordListオブジェクトを作成してから、WordListが必要になるまで、ajaxリクエストを呼び出すことなく残りのプログラムを渡す必要がありますアクセスしましたか?

コールバックを使用しないと、AJAXリクエストが実行される前に残りのコードがWordListを評価しようとしているため、実際にリザベーションが満たされていても、ブラウザは現在の 'ループ' readystatechangeコールバックを実行してリストを作成する前に終了するようにしてください。あなたは同期AJAX呼び出しを使用することができ、または私はおそらく次のようにあなたのXHR機能を書き換えます:あなたは真のグローバルので、他のプログラムが外部ローカルの を使用することができますに単語リストを設定したい場合は

function wordlist(url,withwords) { 
    var xhr = // create your xhr object; 
    xhr.onload = function (data) { 
     withwords(parsetolist(data)); 
    } 
    xhr.send() 
} 

wordlist('dict1.txt', function(words) { 
    // pass words around to other functions 
    filterwords(words); 
    randomizewords(words); 
    // or use it here 
    console.log(words[2]); 
} 

コードを使用すると、単語リストを毎回のコールバックを行う関数に変更する必要があります。少なくとも遅く評価することができます。

function wordlist2(url) { 
    var evaluated = false; 
    var response = function (index, withword) { 
     if (evaluated) { withword(evaluated[index]); } 
     else { 
      wordlist(url, function(words) { 
       evaluated = words; 
       withword(words[index]); 
      }) 
     } 
    } 
    return response; 
} 
ALAMI.WORDLIST = wordlist2('dict1.txt'); 
ALAMI.WORDLIST(2,function (word) { console.log(word); }); 
+0

ありがとうございます、あなたは絶対に正しいです。幸い私はすでにそれを発見し、私の解決策を改良しました。あなたの考えを教えてくれるなら、私の更新されたコードのjsfiddleはここにありますか? http://jsfiddle.net/d5ANd/10/ また、明確にするために、ページが読み込まれたときにWordlistをロードし、残りのユーザー全体で配列としてアクセスできるようにしたい遊びます)。 – person0

+0

あなたのコメントを見る前に、もう少し拡張しました。私はjsfiddleをチェックアウトします。 – Cyclone

+0

はうまく見えますが、AJAX用の従来のブラウザサポートをjqueryのようなライブラリを使って試してみたいと思っているのであればお勧めします。もう1つの便利なパターンは、イベントパッシングを使用してリスナーの束をワードリストに添付することができるため、ワードリストがいっぱいになるとすべてが呼び出されます...これは、単語リストにはさまざまな点があり、どのように独立しているのかが分かります。 – Cyclone

1

XMLHttpRequest()オブジェクトをどのように使用しているかに問題があります。をajaxRequest.open("GET", URL, true);に指定したため、実際には非同期スレッドで要求が完了してメインスレッドがブロックされないように要求しています。私はconsole.logをマークしてきた場所がmainthreadである

<html> 
<head> 
<title>ALAMI Test</title> 
<script language="JavaScript"> 
function doit(URL) { 
    console.log('mainthread - doit begin'); 
    var ajaxRequest = new XMLHttpRequest(); 
    ajaxRequest.open("GET", URL, true); 
    ajaxRequest.onreadystatechange = function() { 
    if (ajaxRequest.readyState === 4) { 
     console.log('asyncthread - readystatechange begin'); 
     var ajaxResponse = ajaxRequest.responseText.split("\n"); 
     var extensionLocation = URL.lastIndexOf('.'); 
     console.log('asyncthread - readystatechange end'); 
    } 
    } 
    console.log('mainthread - ajaxRequest.send'); 
    ajaxRequest.send(null); 
    console.log('manthread - doit end'); 
} 
</script> 
</head> 
<body> 
<input type="button" value="doit" onclick="doit('http://localhost/fulldictionary.txt')"/> 
</body> 

注:これは、HTMLアプリケーションのための良いデザインですが、それは結果より良いの処理方法をよりよく理解する必要があり、以下の例を取りますであり、これはasyncthreadにあります。スクリプトを実行した場合、あなたは次のテキストがコンソールに表示されるはずです:あなたは、あなたのスクリプトを書いたか

LOG: mainthread - doit begin 
LOG: mainthread - ajaxRequest.send 
LOG: manthread - doit end 
LOG: asyncthread - readystatechange begin 
LOG: asyncthread - readystatechange end 

方法、あなたは結果が同期的に発生していると仮定してきた、すなわち

LOG: mainthread - doit begin 
LOG: mainthread - ajaxRequest.send 
LOG: asyncthread - readystatechange begin 
LOG: asyncthread - readystatechange end 
LOG: manthread - doit end 

あなたのスクリプトが動作しない理由です。正しいデザインは、asynchthreadを使って作業を続けることですが、見つかったレコードをALAMIオブジェクトに「ポストバック」するために使用します。 mainthreadが完了すると、ワードリストではなく、あなたがこのようにそれをリライトする必要があり、まだ不明であるため

ALAMI.Hangman.Wordlist = ALAMI.XHR.Get('fulldictionary.txt'); 

ALAMI.XHR.Get('fulldictionary.txt'); 

そして内だから、あなたは、次のコード行を使用することはできませんあなたのasyncthreadを実装するには、あなたのWordlistに値を設定する必要があります。

つまり、いくつかの再設計が必要です。

+0

はい、私はあなたがそれを誰よりも説明したと思います。しかし、あなたが私のjsfiddleを見てコメントしたいと思っているなら、私はすでにすべてのデザインをやり直しました:http:// jsfiddle .net/d5ANd/10/ あなたが問題を十分に解決したと思ったら教えてください。 – person0

+0

@ Proud_to_be_Noobが良く見えます。 –

関連する問題