.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 风格的好处:
- 可读性更好:链式调用,代码更清晰
- 更灵活:可以在不同地方添加回调
- 支持链式调用:便于处理多个异步操作
- 更好的错误处理:可以集中处理错误
这种模式非常适合处理各种网络请求的场景。
