什么是 jQuery deferred.isRejected() 方法?
在前端开发中,异步操作是家常便饭。无论是发送 Ajax 请求、加载图片,还是处理用户交互事件,我们经常需要等待某些任务完成后再执行下一步。jQuery 为此提供了一套强大的异步处理机制,其中 deferred 对象就是核心之一。
deferred.isRejected() 方法是 jQuery 中用于判断一个 deferred 对象是否已经被拒绝(rejected)的工具。它的返回值是一个布尔值:true 表示该异步任务已经失败,false 表示尚未失败或仍在进行中。
你可以把它想象成一个“状态检查器”——就像你寄出快递后,通过物流单号查询包裹是否“已拒收”一样,isRejected() 就是帮你查看异步任务是否“失败了”。
这个方法在处理复杂流程时特别有用,比如在多个异步请求中,你希望知道是否有某个请求失败,从而决定后续流程是继续尝试、跳过还是报错。
deferred 对象的生命周期与状态
在深入 isRejected() 之前,先理解 deferred 对象的三种状态:
- pending(待定):初始状态,异步操作尚未完成。
- resolved(成功):异步操作成功完成。
- rejected(拒绝):异步操作失败。
这三种状态是互斥的,一旦进入某个状态,就无法再改变。而 deferred.isRejected() 正是用于检测当前对象是否处于“rejected”状态。
💡 小贴士:
deferred不是直接创建的,而是通过$.Deferred()构造函数生成。它类似于 Promise 的前身,在 jQuery 1.5 中引入。
状态转换示例
// 创建一个 deferred 对象
const deferred = $.Deferred();
// 初始状态为 pending
console.log(deferred.state()); // 输出: pending
// 模拟异步操作成功
setTimeout(() => {
deferred.resolve('任务完成');
}, 1000);
// 模拟异步操作失败
setTimeout(() => {
deferred.reject('网络超时');
}, 500);
在上面的例子中,deferred.reject() 会将状态设为 rejected,此时调用 isRejected() 就会返回 true。
如何使用 jQuery deferred.isRejected() 方法?
deferred.isRejected() 是一个无参数的方法,调用后直接返回布尔值。它不修改状态,只用于查询。
基本语法
deferred.isRejected()
返回值:
true:对象已被拒绝false:对象未被拒绝(可能还在 pending 或已 resolved)
实际应用案例
假设你正在开发一个图片加载器,需要同时加载三张图片。如果其中任意一张失败,就显示“加载失败”提示。
// 创建三个 deferred 对象,模拟图片加载
const img1 = $.Deferred();
const img2 = $.Deferred();
const img3 = $.Deferred();
// 模拟加载过程:第一张成功,第二张失败,第三张成功
setTimeout(() => {
img1.resolve('图片1加载成功');
}, 1000);
setTimeout(() => {
img2.reject('图片2请求失败');
}, 800);
setTimeout(() => {
img3.resolve('图片3加载成功');
}, 1200);
// 检查是否有一个被拒绝
function checkLoadStatus() {
const isImg1Rejected = img1.isRejected();
const isImg2Rejected = img2.isRejected();
const isImg3Rejected = img3.isRejected();
console.log('图片1是否被拒绝:', isImg1Rejected); // false
console.log('图片2是否被拒绝:', isImg2Rejected); // true
console.log('图片3是否被拒绝:', isImg3Rejected); // false
// 如果任意一张被拒绝,就提示失败
if (isImg1Rejected || isImg2Rejected || isImg3Rejected) {
alert('部分图片加载失败,请检查网络');
} else {
alert('所有图片加载成功');
}
}
// 5秒后检查状态
setTimeout(checkLoadStatus, 1500);
在这个例子中,isRejected() 帮我们精准判断了哪张图片失败,从而做出相应处理。
与其他状态检测方法对比
deferred.isRejected() 并不是孤立存在的,它与 isResolved() 和 state() 方法共同构成了状态查询体系。
| 方法 | 作用 | 返回值 |
|---|---|---|
deferred.isResolved() |
检查是否已成功 | true / false |
deferred.isRejected() |
检查是否已被拒绝 | true / false |
deferred.state() |
获取当前状态(pending/resolved/rejected) | 字符串 |
三者结合使用示例
const task = $.Deferred();
// 模拟异步任务
setTimeout(() => {
task.reject('任务失败');
}, 1000);
// 1.5秒后检查状态
setTimeout(() => {
console.log('当前状态:', task.state()); // rejected
console.log('是否已拒绝:', task.isRejected()); // true
console.log('是否已成功:', task.isResolved()); // false
}, 1500);
通过组合使用这些方法,你可以构建出更智能的流程控制逻辑。比如在接口调用失败后自动重试,或跳过失败项继续执行。
实际项目中的典型应用场景
在真实项目中,deferred.isRejected() 常用于以下场景:
1. 表单提交与错误处理
当用户提交表单时,可能需要同时发送多个请求(如保存数据、上传附件、发送通知)。一旦某个请求失败,应立即提示用户。
const saveForm = $.Deferred();
const uploadFile = $.Deferred();
const sendNotification = $.Deferred();
// 模拟提交过程
setTimeout(() => {
saveForm.resolve('数据已保存');
}, 800);
setTimeout(() => {
uploadFile.reject('文件过大,无法上传');
}, 600);
setTimeout(() => {
sendNotification.resolve('通知已发送');
}, 1000);
// 检查是否有失败项
function handleFormSubmission() {
const hasError = saveForm.isRejected() || uploadFile.isRejected() || sendNotification.isRejected();
if (hasError) {
alert('提交失败,请检查上传文件或网络连接');
} else {
alert('表单提交成功');
}
}
// 1.2秒后检查
setTimeout(handleFormSubmission, 1200);
2. 资源预加载与容错机制
在游戏或网页应用中,常需预加载资源。若某个资源加载失败,可降级为默认值。
const resources = [
$.Deferred(), // 图片
$.Deferred(), // 音频
$.Deferred() // 字体
];
// 模拟加载
setTimeout(() => resources[0].resolve('img.png'), 500);
setTimeout(() => resources[1].reject('audio.mp3 不存在'), 400);
setTimeout(() => resources[2].resolve('font.woff'), 600);
// 预加载完成后检查
setTimeout(() => {
const failed = resources.some(r => r.isRejected());
if (failed) {
console.warn('部分资源加载失败,使用默认资源');
// 可以触发 fallback 逻辑
} else {
console.log('所有资源加载完成');
}
}, 700);
注意事项与常见误区
1. isRejected() 只能用于 deferred 对象
这个方法不能用于普通 Promise 或回调函数。如果你使用的是原生 Promise,应改用 Promise.catch() 或 then() 的失败回调。
// ❌ 错误用法
const promise = new Promise((resolve) => setTimeout(resolve, 1000));
console.log(promise.isRejected()); // 报错:方法不存在
// ✅ 正确做法
promise.catch(err => {
console.log('Promise 失败:', err);
});
2. 一旦状态确定,无法更改
deferred 的状态是单向不可逆的。一旦调用 resolve() 或 reject(),就不能再改变。
const d = $.Deferred();
d.resolve('成功');
console.log(d.isRejected()); // false
// 再次调用 reject 不会生效
d.reject('错误'); // 不会改变状态
console.log(d.isRejected()); // 仍然是 false
3. 在链式调用中需注意时机
如果在 .then() 中使用 isRejected(),要确保异步任务已经执行完毕。
const task = $.Deferred();
task.then(() => {
console.log('任务完成');
}).catch(() => {
console.log('任务失败');
});
// 但此时状态尚未确定,isRejected() 仍为 false
console.log(task.isRejected()); // false
必须等待回调执行完毕后再检查。
总结
jQuery deferred.isRejected() 方法虽然看似简单,却在异步流程控制中扮演着关键角色。它让你能精准判断一个异步操作是否失败,从而实现更健壮的错误处理机制。
无论是表单提交、资源加载,还是多任务并行处理,掌握这个方法都能帮你写出更可靠的代码。它就像一个“状态探针”,在关键时刻告诉你:“这个任务,失败了。”
在实际开发中,建议结合 isResolved() 和 state() 一起使用,构建完整的状态监控体系。虽然现代 JavaScript 已广泛使用原生 Promise,但在维护老项目或使用 jQuery 的场景下,deferred.isRejected() 依然是不可或缺的工具。
如果你正在处理复杂异步逻辑,不妨试试在关键节点加入 isRejected() 检查,你会发现程序的稳定性大幅提升。