0

作成した AJAX 呼び出しに基づいてオブジェクトを元に戻す必要があります。ただし、関数の実行が完了する前に AJAX 呼び出しが終了しないことがわかりました。

私はさまざまなアプローチを試みましたが、それぞれが同じ非同期の問題に戻っているようです - そして私は同期呼び出しをしたくありません。

元に戻す必要があるかどうかを判断する前に、AJAX 呼び出しが完了して応答が得られるまで待つにはどうすればよいですか?

$(document).ready(function() {

$.ajax
({
    type: "GET",
    url: "quizData.xml",
    dataType: "xml",
    success: function(xml)
    {
        var questionIdCount = 0;
        $(xml).find('question').each(function()
        {
            questionIdCount++;
            $("#question-container").append("<div class=\"question\" id=\"question-number-" + questionIdCount + "\">" + $(this).text() + "</div>");

            $("#question-number-" + questionIdCount).data('id', questionIdCount);

            $(".question").droppable(
            {

            }
            );

        });

        var answerIdCount = 0;
        $(xml).find('answer').each(function()
        {
            answerIdCount++;
            $("#answer-container").append("<div class=\"answer-id\" id=\"answer-number-" + answerIdCount + 
            "\">" + answerIdCount + "</div><div class=\"answer\">" + $(this).text() + "</div>");    

            $("#answer-number-" + answerIdCount).data('id', answerIdCount);

            $(".answer-id").draggable({
              revert: function(socketObj)
              {
                 if(!socketObj)
                 {
                     return true;
                 }
                 else
                 {
                    var questionId = $("#" + socketObj.attr('id')).data('id')
                    var answerId = $("#" + $(this).attr('id')).data('id');

                    return checkAnswer(questionId, answerId);
                 }


              },
              containment: "#containment-wrapper",
              scroll: true
            });


        }); 
    }
});
  $(document).ready(function() {

$.ajax
({
    type: "GET",
    url: "quizData.xml",
    dataType: "xml",
    success: function(xml)
    {
        var questionIdCount = 0;
        $(xml).find('question').each(function()
        {
            questionIdCount++;
            $("#question-container").append("<div class=\"question\" id=\"question-number-" + questionIdCount + "\">" + $(this).text() + "</div>");

            $("#question-number-" + questionIdCount).data('id', questionIdCount);

            $(".question").droppable(
            {

            }
            );

        });

        var answerIdCount = 0;
        $(xml).find('answer').each(function()
        {
            answerIdCount++;
            $("#answer-container").append("<div class=\"answer-id\" id=\"answer-number-" + answerIdCount + 
            "\">" + answerIdCount + "</div><div class=\"answer\">" + $(this).text() + "</div>");    

            $("#answer-number-" + answerIdCount).data('id', answerIdCount);

            $(".answer-id").draggable({
              revert: function(socketObj)
              {
                 if(!socketObj)
                 {
                     return true;
                 }
                 else
                 {
                    var questionId = $("#" + socketObj.attr('id')).data('id')
                    var answerId = $("#" + $(this).attr('id')).data('id');

                    return checkAnswer(questionId, answerId);
                 }


              },
              containment: "#containment-wrapper",
              scroll: true
            });


        }); 
    }
});


function checkAnswer(questionId, answerId)
{
     var ajaxAnswer;
     $.ajax
     ({
        type: "POST",
        url: "getQuizAnswers.php",
        dataType: "xml",
        data: "questionId=" + questionId + "&answerId=" + answerId,
        success: function(xml)
        {
            console.log($(xml));
            $(xml).find("answer").each(function()
            {
                //alert($(this).text());
                if($(this).text() == "true")
                    ajaxAnswer = true;
                else
                    ajaxAnswer = false;

            });             
        }
      })

    return ajaxAnswer;  
}



});


});
4

2 に答える 2

0

すでに折り返しの電話があります。

success: function(xml){
  }

ajaxリクエストが正常終了した時のコールバック関数です。

checkAnswer(questionId, answerId)そのため、必要な場所のどこかから呼び出します。

他の両方の ajax リクエストが終了したら checkAnswer を呼び出すには、次のようにします。

$.when($.ajax("/page1.php"), $.ajax("/page2.php"))
  .then(checkAnswer(questionId, answerId));

jQuery.when

于 2012-07-26T19:50:01.500 に答える
0

スペンサー、

オブジェクトを使用して物事を制御できるようにする必要がありdeferredます。また、コードを再編成して、内部の ajaxcheckAnswerが応答した場合にのみドラッグ可能が設定されるようにする必要があります。

私はこれのすべての面で 100% の自信があるわけではありませんが、次のようになります。

$(document).ready(function() {
    function setDraggable(revert) {
        $(".answer-id").draggable({
            revert: revert
            containment: "#containment-wrapper",
        });
    }
    $.ajax({
        type: "GET",
        url: "quizData.xml",
        dataType: "xml",
        success: function(xml) {
            var questionIdCount = 0;
            $(xml).find('question').each(function() {
                questionIdCount++;
                $("#question-container").append("<div class=\"question\" id=\"question-number-" + questionIdCount + "\">" + $(this).text() + "</div>");
                $("#question-number-" + questionIdCount).data('id', questionIdCount);
                $(".question").droppable({});
            });
            var answerIdCount = 0;
        $(xml).find('answer').each(function() {
            answerIdCount++;
            $("#answer-container").append("<div class=\"answer-id\" id=\"answer-number-" + answerIdCount + "\">" + answerIdCount + "</div><div class=\"answer\">" + $(this).text() + "</div>");
            $("#answer-number-" + answerIdCount).data('id', answerIdCount);
            if(socketObj) {
                var questionId = $("#" + socketObj.attr('id')).data('id')
                var answerId = $("#" + $(this).attr('id')).data('id');
                $.when(checkAnswer(questionId, answerId)).done(function() {
                    setDraggable(true);
                }).fail(function() {
                    setDraggable(false);
                });
            }
            else {
                setDraggable(true);
            }
            scroll: true
        });
        }
    });
    function checkAnswer(questionId, answerId) {
        var ajaxAnswer = true;//remains true unless an incorrect answer is received
        var def =  new $.Deferred();
        $.ajax({
            type: "POST",
            url: "getQuizAnswers.php",
            dataType: "xml",
            data: {"questionId":questionId, "answerId":answerId},
            success: function(xml) {
                console.log($(xml));
                $(xml).find("answer").each(function() {
                    ajaxAnswer = ajaxAnswer && ($(this).text() == "true");
                });
                if(ajaxAnswer) 
                    def.resolve();//success
                else 
                    def.reject();//failure
            },
            error: function(){
                def.reject();//assume failure if ajax fails
            }
        });
        return def;//IMPORTANT!!
    }
});

これはややトリッキーで、説明する必要があります...

から始まると、遅延オブジェクトcheckAnswerが返されることがわかります。これは、近い将来のある時点で解決または拒否されます ("getQuizAnswers.php" が応答したとき)。

ループに戻る.find('answer').each(...)と、コードが裏返しになっていることがわかります。現在、checkAnswer()draggabe 内で呼び出す代わりに、draggable がcheckAnswer(より具体的には、checkAnswer の deferred が解決または拒否されたことに応じて) に応じて設定されます。

ドラッグ可能なコードはいくつかの条件下で設定する必要があるため、ドラッグ可能なコードはユーティリティ関数に移動されたため、重複が回避されました。動作をより具体的に制御するには、この関数にさらにパラメーターを渡す必要がある場合があります (特に jQuery セレクター)。

これには調整/デバッグが必要な場合があり、より簡単なアプローチがあるかもしれませんが、これがすぐに思い浮かびます。

于 2012-07-27T00:30:23.517 に答える