2013-10-31 3 views
2

비동기식 AJAX/JSON 게시물을 통해 데이터베이스에 응답하는 퀴즈를 작성하고 있습니다. 데이터베이스는 응답이 정확한지 알기위한 표시기를 반환합니다.JSON/AJAX 게시물에 지연 기능을 구현하는 데 도움이 필요합니다.

$ .Deferred를 사용하는 동료는 데이터베이스 호출이 반환되는 데 걸리는 시간을 알 수 없으므로 동료는 $ .Deferred를 사용하여 좋습니다. 나는 AJAX 게시물로 이것을 수행하는 분명한 예를 찾을 수 없었다. StackOverflow 전문가 중 한 명이이 문제에 대한 지침을 제공 할 수 있다고 생각했습니다.

이 코드는 "응답 제출"버튼을 클릭하면 실행되는 호출 기능에 있습니다.

 var answerResult = recordAnswer(answer); 
    if (answerResult.IsAnswerCorrect) { 
     // Show student if her quiz answer was correct. 
    } 

다음은 recordAnswer 함수입니다. 이 개체 (IsAnswerCorrect 및 IsQuizCompleted)에 몇 가지 값을 반환해야합니다. 내 양식이 성공적으로 AJAX 호출을 만들고 값이 '결과'로 반환됩니다. 그러나 때로는 반환되는 'answerResult'값이 위의 호출 코드에서 '정의되지 않음'으로 되돌아와 결과적으로 중단됩니다. 지연된 통화로 변경하면 문제가 해결됩니다.

var recordAnswer = function (answer) { 

    var quizSessionQuestionId = $('#hidden_quizSessionQuestionId').val(); 
    var numberOfHintsUsed = 0; 

    var answerResult; 

    $.ajax({ 
    url: QuizConfig.RecordAnswerDataAction, // Tied to RecordAnswer in BaseQuizController. 
    type: 'POST', 
    async: false, 
    dataType: 'json', 
    data: { 
     "quizSessionQuestionId": quizSessionQuestionId, 
     "value": answer, 
     "numberOfHintsUsed": numberOfHintsUsed, 
     "markCompleteIfWrong": false 
    }, 
    success: function (result) { 
     answerResult = result; 
    }, 
    error: function (request, errorm) { 
     jAlert("Unable to record answer.", "An error occurred while saving this answer."); 
     return; 
    } 
    }); 

    return answerResult; 
}; 

이 연구 동안

가 나는 "주의 BROKEN CODE"때문이다 (answerResult = 결과의 할당) 위에 도포 패턴을 나타내는 다음 가이드 발견 "A는 비동기식이다." :) http://jqfundamentals.com/chapter/ajax-deferreds

어쨌든 내가 지금까지 가지고있는 깨진 방법보다는 지연된 방법론을 사용하도록 위의 코드를 조정하는 방법을 보여주십시오. 당신의 도움을 주셔서 감사합니다. 당신이 비록

+1

가능한 복제본 [AJAX 호출에서 응답을 반환하는 방법] (http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call) – Musa

답변

1

$.Deferred() 개체는 약속을위한 중개인으로 생각하는 것이 가장 좋습니다. 약속을 사용한 비동기 프로그래밍의 일반적인 패턴은 값이 아닌 약속을 반환하는 함수를 사용하는 것입니다. 다음과 같이 예를 들어, 사용자가 게시 된 코드를 다시 작성할 수 있습니다

var recordAnswer = function (answer) { 
    ... 
    var answerResult = $.Deferred(); 

    $.ajax({ 
     ... 
     success: function (result) { 
      answerResult.resolve(result); 
     }, 
     error: function (request, errorm) { 
      jAlert("Unable to record answer.", "An error occurred while saving this answer."); 
      answerResult.reject(); 
     } 
    }); 

    return answerResult.promise(); 
}; 

후 오히려 즉시 사용에 반환 값 것보다 해결을위한 약속을들을 수 있습니다 recordAnswer를 사용하여 코드 :

var fetchingAnswer = recordAnswer(answer); 

fetchingAnswer.then(function(result) { 
    // do stuff with the result 
} 

deferred.then()은 거부 또는 해결 후에 실행되므로 deferred.done() (해결 된 약속의 경우) 및 deferred.fail() (거부 된 약속의 경우)을 사용할 수 있습니다.

==========================================

아래는 관심있는 사람을 대상으로 @giaour의 권장 사항을 기반으로 한 전체 구현입니다. 감사.

제출 버튼을 클릭하면 호출됩니다.

 var fetchAnswer = recordAnswer(answer); 
    fetchAnswer.then(function (result) { 
     // Do something 
     recalculateProgress(result.IsComplete, result.IsAnswerCorrect); 
    }); 

이것은 AJAX 게시물과 함께 사용됩니다.

var recordAnswer = function (answer) { 

    var quizSessionQuestionId = $('#hidden_quizSessionQuestionId').val(); 
    var numberOfHintsUsed = 0; 

    var promiseBroker = $.Deferred(); 
    $.ajax({ 
    url: QuizConfig.RecordAnswerDataAction, 
    type: 'POST', 
    async: false, 
    dataType: 'json', 
    data: { 
     "quizSessionQuestionId": quizSessionQuestionId, 
     "value": answer, 
     "numberOfHintsUsed": numberOfHintsUsed, 
     "markCompleteIfWrong": false 
    }, 
    success: function (result) { 
     promiseBroker.resolve(result); 
    }, 
    error: function (request, errorm) { 
     jAlert("Unable to record answer.", "An error occurred while saving this answer."); 
     promiseBroker.reject(); 
     return; 
    } 
    }); 

    return promiseBroker.promise(); 
}; 

여러분 모두를 도와 주셔서 감사합니다.

+0

@ giaour 솔루션에 감사드립니다. 그게 내가 만난거야. –

0

비동기 코드는, 콜백 FUNC

var answerResult = recordAnswer(answer, function(answerResult){ 
    if (answerResult.IsAnswerCorrect) { 
     // Show student if her quiz answer was correct. 
    } 
); 

var recordAnswer = function (answer , cb) { 
    $.ajax({ 
    ....... 
    success: function (result) { 
     cb(result); 
    }, 
    ....... 
0

가장 큰 문제는 이런 식으로 당신이 return answerResult; 성공 기능 후에 실행하는 것을 보장 할 수 없습니다 가고 있다는 것입니다을 사용하여, 다음과 같이해야한다 async를 false로 설정하십시오.

따라서 더 나은 접근 방법은 성공을 트리거하고 수행해야 할 작업을 트리거하는 콜백 함수가 될 것이라고 생각합니다. recordAnswer 함수에 호출 객체를 전달하고 콜백 함수에 사용할 수 있습니다.

+0

좋아, 그냥 농부 1,992 솔루션을 찾으십시오. 그것은 내가 말하는 것이지만 코드로 작성되었습니다. – Jacobson