Jquery Ajax的beforeSend、success、error和complete是什么意思?

59

我有一个关于多个ajax函数的问题,在第二个ajax post的beforeSend函数执行之前,第一个ajax的complete函数已经执行了。

我在发送之前添加到占位符中的加载类适用于第一个ajax调用。但是,第一个ajax请求完成后不久,该类别被删除,并且不再附加到第二次及更多次调用中(请记住递归调用)。

调试时显示第二个ajax调用的beforeSend函数首先被调用,第一个ajax调用的complete函数稍后才被调用。这很明显,因为从第一个ajax调用插入页面的返回数据开始第二个调用。

简而言之,它混乱了。 有没有办法解决这个问题?

函数代码如下:

function AjaxSendForm(url, placeholder, form, append) {
var data = $(form).serialize();
append = (append === undefined ? false : true); // whatever, it will evaluate to true or false only
$.ajax({
    type: 'POST',
    url: url,
    data: data,
    beforeSend: function() {
        // setting a timeout
        $(placeholder).addClass('loading');
    },
    success: function(data) {
        if (append) {
            $(placeholder).append(data);
        } else {
            $(placeholder).html(data);
        }
    },
    error: function(xhr) { // if error occured
        alert("Error occured.please try again");
        $(placeholder).append(xhr.statusText + xhr.responseText);
        $(placeholder).removeClass('loading');
    },
    complete: function() {
        $(placeholder).removeClass('loading');
    },
    dataType: 'html'
});
}

而数据包含以下片段的javascript/jquery代码,该代码检查并启动另一个ajax请求。

<script type="text/javascript">//<!--
 $(document).ready(function() {
    $('#restart').val(-1)
    $('#ajaxSubmit').click();
});
//--></script>
2个回答

101

也许您可以尝试以下方法:

var i = 0;
function AjaxSendForm(url, placeholder, form, append) {
var data = $(form).serialize();
append = (append === undefined ? false : true); // whatever, it will evaluate to true or false only
$.ajax({
    type: 'POST',
    url: url,
    data: data,
    beforeSend: function() {
        // setting a timeout
        $(placeholder).addClass('loading');
        i++;
    },
    success: function(data) {
        if (append) {
            $(placeholder).append(data);
        } else {
            $(placeholder).html(data);
        }
    },
    error: function(xhr) { // if error occured
        alert("Error occured.please try again");
        $(placeholder).append(xhr.statusText + xhr.responseText);
        $(placeholder).removeClass('loading');
    },
    complete: function() {
        i--;
        if (i <= 0) {
            $(placeholder).removeClass('loading');
        }
    },
    dataType: 'html'
});
}

如果beforeSend语句在complete语句之前被调用,i将大于0,因此它不会移除类。然后只有最后一次调用才能移除它。

我无法测试它,请告诉我它是否有效。


我尝试了你的解决方案,它给了我惊人的结果。首先,我使用了var requestNumber = 0,并在beforeSend中++它,在complete/always中进行检查。它显示requestNumber == 2和--结果为1,这在检查中返回false,加载类没有被移除。然而,它从未被移除,因为我不知道为什么,它会为整个序列生成一个额外的请求。现在罪魁祸首已经找到,我认为很容易解决或发布一个错误请求。 - Rehan Anis
如果函数失败了,那么它会进入错误处理和完成处理。如果我只想让它在完成处理中,我可以在完成处理的结尾处返回1,这样它就不会进入错误处理了吗? - Robot Boy

11

使用jQuery的promise API,事实上更容易实现:

$.ajax(
            type: "GET",
            url: requestURL,
        ).then((success) =>
            console.dir(success)
        ).failure((failureResponse) =>
            console.dir(failureResponse)
        )

或者,您可以为每个结果回调函数传递 bind 函数之一;参数的顺序是:(success, failure)。 只要指定至少有一个参数的函数,就可以访问响应。 因此,例如,如果您想要检查响应文本,只需执行以下操作:

$.ajax(
            type: "GET",
            url: @get("url") + "logout",
            beforeSend: (xhr) -> xhr.setRequestHeader("token", currentToken)
        ).failure((response) -> console.log "Request was unauthorized" if response.status is 401

谢谢更新,我已经更新了我的代码,并用新定义的承诺函数fail、done和always替换了成功、错误和完成回调函数。然而,它们并没有解决问题,因为我应用了@Nathan P提供的解决方案,但问题是不同的。 - Rehan Anis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接