2012-02-25 4 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]을 사용하고 배열에서 그 장소에 저장되어있는 어떤 문자열의 값을 반환 가질 수있을 것입니다.

또한 내 아약스 함수를 무한한 횟수로 사용할 수있는 보편적 인 방법으로 만들려고합니다. 예를 들어 :

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는 내가 자바 스크립트에서 만드는 모든 것에 대한 내 개인 네임 스페이스입니다 (YAHOO 또는 그 반대). fulldictionary.txt는 .js 파일 및 html 파일과 같은 폴더에 있기 때문에 유효한 URL입니다.이 코드에 대한 모든 것은'ajaxResponse'의 값을 반환하는 것을 제외하고는 작동합니다. – person0

답변

0

이 질문에 답하는 모든 분들께 감사드립니다. 모든 답변은 질문에 대답하는 데 도움이되는 유용한 정보를 담고 있었지만 문제를 해결하는 데 필요한 모든 이해가 하나도 없으므로 답변을 게시하고 있습니다. 다음과 같이

솔루션은 다음과 같습니다

  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

그래, 결국 내 문제는 해결되지 않습니다. 내 코드 전체에서 bazillion 다른 함수에서'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를로드 한 다음 나머지 사용자가 페이지를 방문하는 동안 Array로 액세스 할 수있게하려는 것이 좋습니다. 놀이). – person0

+0

나는 당신의 코멘트를보기 전에 jsfiddle를 살펴볼 것입니다. – Cyclone

+0

괜찮아 보이지만 AJAX에 대한 '레거시 (legacy)'브라우저 지원을 jquery와 같은 라이브러리를 사용하려는 경우 제안합니다. 사용할 수있는 또 다른 유용한 패턴은 이벤트 전달을 사용하여 여러 개의 청취자를 단어 목록에 첨부 할 수 있으므로 단어 목록이 채워질 때 모두 수신자가 될 수 있습니다 ... 이는 얼마나 많은 코드에 따라 더 명확한 코드로 이어지지 않을지 모릅니다. 서로 다른 단어 목록에 액세스 할 수 있으며, 어떻게 독립적인지 확인할 수 있습니다. – 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 오브젝트로 "포스트 백"하는 데 사용하십시오. 그래서, 당신은 다음 코드 줄을 사용할 수 없습니다

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

그리고 내 다음 mainthread이 완료되면, 단어 목록은 아직 알 수 없기 때문에

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

대신,이로 다시 작성해야 asyncthread를 구현하면 Wordlist를 채워야합니다.

즉 몇 가지 재 설계가 필요합니다.

+0

예, 제 생각에 당신이 누군가보다 더 잘 설명했다고 생각합니다. 그러나 jsfiddle에 대해보고 의견을 말하고 싶다면 이미 모든 재 설계 작업을 수행했습니다. http : // jsfiddle .net/d5ANd/10/ 그 문제가 충분히 해결되었다고 생각되면 알려주십시오. – person0

+0

@ Proud_to_be_Noob이 더 좋습니다. –

관련 문제