2016-10-24 3 views
0

) 텍스트 파일에서 행을 읽으려는 경우 파일에서 한 행을 선택하여 HTML 페이지의 div에 삽입하십시오.JQuery.when() 및 비동기 이벤트가 작동하지 않는 경우 (

var chosenWord="original word"; 

function wordFromFile(fileName) { 
    $.get(fileName, function(data) { 
     var lines = data.split("\n"); 
     var lineCount = lines.length; 
     var randomIndex = Math.floor(Math.random() * ((lineCount-1) + 1)); 
     var word = lines[randomIndex]; 
     window.chosenWord = word; 
     console.log("wordFromFile: "+chosenWord); 
    }); 
} 

function setRandomWord() { 
    $.when(wordFromFile("http://mypage.com/words.txt")).then(appendWord()); 
} 

function appendWord() { 
    console.log("appendWord: "+window.chosenWord); 
    $('.word').text(window.chosenWord); 
} 

$(function() { 
    if($('body').is('.playpage')) { 
    setRandomWord(); 
    } 

}); 


console shows: 
appendWord: original word 
wordFromFile: particle //when i refresh the page this word changes but appendWord is always "original word" 

은 어떻게하면 그 기능 wordFromFile (파일 이름)를 먼저 완료되도록 할 수 appendWord는 전역 변수 chosenWord에 대해 동일한 값을 가져옵니다? 왜 when() 및 then() 함수가 내 코드에서 작동하지 않는지 이해할 수 없습니다.

+0

wordFromFile은 Promise를 반환하지 않습니다. 실제로는 아무것도 반환하지 않습니다. $ .when는 'undefined'가 아닌 Promises와 함께 작동합니다. –

답변

0

wordFromFile()에서 약속을 반환해야합니다. 당신이 당신의 마지막 chosenWord 값이 약속의 해결 값하려는 경우

function wordFromFile(fileName) { 
    return $.get(fileName).then(function(data) { 
     var lines = data.split("\n"); 
     var lineCount = lines.length; 
     var randomIndex = Math.floor(Math.random() * lineCount); 
     var word = lines[randomIndex]; 
     window.chosenWord = word; 
     console.log("wordFromFile: "+chosenWord); 
     return chosenWord; 
    }); 
} 

그리고, 당신은 그것을 .then() 핸들러에서 반환해야합니다. 또한, $.get()의 콜백을 .then() 처리기로 변경하여 훨씬 일관성있게 처리합니다. 일반적으로 약속을 사용하고 나면 작업 내에서 일관되게 사용하고 약속 내의 구식 콜백을 섞어 놓지 않을 것입니다. 그렇게하면 자동 오류 전파 및 오류 처리 기능 중 일부가 제공하는 기능을 상실 할 수 있습니다.

다음, 당신은 이미 약속을 반환 setRandomWord()wordFromFile() 때문에 전혀 $.when()를 사용할 필요가 없습니다 당신은 appendWord 후 괄호없이 .then()에 함수 참조를 전달해야합니다 요약하자면

function setRandomWord() { 
    wordFromFile("http://mypage.com/words.txt").then(appendWord); 
} 

:

  1. 반환 wordFromFile()에서 약속
  2. 사용 012의 내부 .then() 핸들러대신 jQuery 콜백을 사용하십시오.
  3. $.when() 주위에 필요하지 않으므로 wordFromFile()을 제거하십시오.
  4. .then()에 함수 참조를 전달할 때 appendWord 뒤에 괄호를 제거하십시오. 약속이 해결 될 때 나중에 .then() 처리기가 언젠가 그것을 호출하도록 허용하는 대신에 appendWord를 호출하는 방식입니다.
  5. 처음 단어를 피하려고하지 않는 한 임의의 숫자 논리가 적절하지 않았습니다.

약속에는 마법의 힘이 없습니다. 그들은 내부적으로 비동기 조작이 어떻게되는지 알지 못합니다. 비동기 작업이 수동으로 약속을 해결할 때 비동기 작업이 완료된 경우에만 알 수 있습니다. 따라서 비동기 작업을 $.when() 안에 넣고 $.when()이 비동기 작업이 완료되면 마술처럼 알 수 있다고 기대할 수 없습니다. 많은 사람들이이 작업을 시도합니다. 따라서 약속에 새로운 사람들이 기대하는 것처럼 보입니다. 대신 약속을 $.when()으로 전달하면 비동기 작업에서 이러한 약속을 해결해야합니다. 귀하의 경우에는 약속이 하나만 있으므로 $.when()은 필요하지 않습니다. 그것은 일반적으로 당신이 기다리고 싶은 하나 이상의 약속이있을 때만 필요합니다. 하나의 약속 만하면 .then()으로 전화하면됩니다.

다른 것들을 참고 사항 : 당신은 결과를 다시 통신하기 위해 전역 변수 chosenWord을 사용하고

  1. .그럴 필요는 없으며 일반적으로 반 패턴으로 간주됩니다.
  2. ajax 호출에서 오류 처리가 없습니다.

이 코드 :

$(function() { 
    if($('body').is('.playpage')) { 
    setRandomWord(); 
    } 

}); 

이 단순화 될 수는 :

$(function() { 
    $("body.playpage").each(setRandomWord); 
}); 

body 태그가에 playpage 클래스가있는 경우, 그것은 setRandomWord()를 호출합니다. 그렇지 않은 경우에는 호출하지 않습니다.


는이 같은 코드에서 chosenWord 세계를 제거 할 수 있습니다 : 선택한 단어가 wordFromFile() 반환이 어떤 .then() 핸들러에 전달 될 수 있도록하는 약속의 해결 값을 만들어

다음
function wordFromFile(fileName) { 
    return $.get(fileName).then(function(data) { 
     var lines = data.split("\n"); 
     var randomIndex = Math.floor(Math.random() * lines.length); 
     var word = lines[randomIndex]; 
     console.log("wordFromFile: "+word); 
     return word; 
    }); 
} 


function setRandomWord() { 
    return wordFromFile("http://mypage.com/words.txt")).then(appendWord); 
} 

function appendWord(word) { 
    console.log("appendWord: "+word); 
    $('.word').text(word); 
} 

$(function() { 
    $("body.playpage").each(setRandomWord); 
}); 

그 약속을 지켜라. appendWord.then() 처리기로 전달하면 단어가 appendWord으로 전달됨을 의미합니다. 그리고 wala no global이 사용됩니다.

+0

정말 고마워요, 이제 작동합니다! – Prosper

+0

@Prosper - 새로운 질문 일 수도 있으므로 질문에 대한 답을 얻을 때 그 대답 옆에있는 녹색 체크 표시를 클릭하여 가장 적합한 대답을 선택해야합니다. 이 둘은 커뮤니티에 귀하의 질문에 대한 답변이 있음을 나타내며 적절한 절차를 밟을 때 평판 포인트를 얻게됩니다. – jfriend00