.done().fail().always() 是 jQuery 的 Ajax 请求(包括 $.post()$.get() 等)的回调函数。它们是 jQuery 的 Deferred/Promise 模式的一部分,用于处理异步操作的结果。

让我详细解释每个方法:

1. .done() - 请求成功时执行

$.post(url, data)
    .done(function(response) {
        // 当服务器返回成功状态码时执行
        // 通常状态码是 200-299
        console.log("请求成功!");
        console.log("服务器返回的数据:", response);
    });

特点:

  • 当 HTTP 状态码是 2xx(如 200 OK)时触发
  • 参数是服务器返回的数据
  • 对应传统的 success 回调

2. .fail() - 请求失败时执行

$.post(url, data)
    .fail(function(jqXHR, textStatus, errorThrown) {
        // 当请求失败时执行
        console.log("请求失败!");
        console.log("状态:", textStatus);
        console.log("错误:", errorThrown);
        console.log("XHR对象:", jqXHR);
    });

参数说明:

  • jqXHR:jQuery XMLHttpRequest 对象
  • textStatus:错误类型字符串,如 “timeout”、”error”、”abort”、”parsererror”
  • errorThrown:抛出的错误信息

常见失败场景:

  • 网络连接失败
  • 服务器返回 4xx 或 5xx 错误
  • 请求超时
  • JSON 解析错误

3. .always() - 无论成功或失败都执行

$.post(url, data)
    .always(function() {
        // 无论成功还是失败都会执行
        console.log("请求完成!");
        // 适合做一些清理工作
    });

4. 组合使用示例

$.post("/api/save", { name: "张三", age: 25 })
    .done(function(response) {
        // 成功处理
        if (response.success) {
            alert("保存成功!ID: " + response.id);
        } else {
            alert("保存失败:" + response.message);
        }
    })
    .fail(function(xhr, status, error) {
        // 失败处理
        if (xhr.status === 401) {
            alert("请先登录!");
        } else if (xhr.status === 404) {
            alert("接口不存在!");
        } else if (xhr.status === 500) {
            alert("服务器内部错误!");
        } else if (status === "timeout") {
            alert("请求超时,请检查网络!");
        } else {
            alert("请求失败:" + error);
        }
    })
    .always(function() {
        // 无论如何都会执行
        console.log("请求处理完毕");
        // 比如隐藏加载动画
        $("#loading").hide();
    });

5. 与传统写法的对比

传统写法:

$.ajax({
    url: "/api/save",
    method: "POST",
    data: { name: "张三" },
    success: function(response) {
        // 成功回调
    },
    error: function(xhr, status, error) {
        // 失败回调
    },
    complete: function() {
        // 完成回调
    }
});

Promise 写法(推荐):

$.post("/api/save", { name: "张三" })
    .done(function(response) { /* 成功 */ })
    .fail(function(xhr, status, error) { /* 失败 */ })
    .always(function() { /* 完成 */ });

6. 链式调用多个 .done()

$.post("/api/user", { id: 123 })
    .done(function(data) {
        console.log("用户数据:", data);
        return $.post("/api/profile", { userId: data.id });
    })
    .done(function(profile) {
        console.log("用户资料:", profile);
        return $.post("/api/orders", { userId: profile.userId });
    })
    .done(function(orders) {
        console.log("用户订单:", orders);
    })
    .fail(function(error) {
        console.log("获取数据失败:", error);
    });

7. 返回的 Promise 可以存储在变量中

// 可以存储 Promise
let saveRequest = $.post("/api/save", data);

// 稍后添加回调
saveRequest.done(function(response) {
    console.log("保存完成:", response);
});

// 或者取消请求
saveRequest.abort();  // 中止请求

总结

方法 对应传统写法 触发时机 用途
.done() success 请求成功(2xx状态码) 处理成功结果
.fail() error 请求失败(4xx, 5xx, 网络错误等) 处理错误情况
.always() complete 无论成功失败 执行清理工作

使用 Promise 风格的好处:

  1. 可读性更好:链式调用,代码更清晰
  2. 更灵活:可以在不同地方添加回调
  3. 支持链式调用:便于处理多个异步操作
  4. 更好的错误处理:可以集中处理错误

这种模式非常适合处理各种网络请求的场景。