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响应后才设置 draggable。

我对这方面的每个方面都不是 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 的延迟被解决或拒绝)。

由于需要在多个条件下设置可拖动,因此将可拖动代码移至实用程序函数中,从而避免重复。您可能需要向此函数传递更多参数以更具体地控制其行为(特别是 jQuery 选择器)。

这可能需要 tweeking/debugging 并且可能有更简单的方法,但这是立即想到的。

于 2012-07-27T00:30:23.517 回答