jQuery deferred.progress() 方法(手把手讲解)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观
前言:为什么需要进度通知?
在现代 Web 开发中,异步操作(如 AJAX 请求、文件上传、复杂计算)是常态。开发者不仅要处理操作的成功或失败,还可能需要实时追踪操作的进度,例如在文件上传时显示百分比,或在数据加载时更新界面。
jQuery 的 Deferred
对象提供了一套优雅的解决方案,而 deferred.progress()
方法正是其中用于监听异步任务进度的核心工具。它像一位“进度追踪员”,允许开发者在任务执行过程中动态获取状态信息,并据此更新用户界面或执行其他逻辑。
本文将从基础概念出发,结合代码示例,逐步讲解 deferred.progress()
的原理、用法及实际应用场景,并通过案例演示如何在真实项目中使用它。
一、Deferred 对象:异步操作的“指挥中心”
1.1 什么是 Deferred 对象?
Deferred
是 jQuery 提供的异步操作管理器,它通过三个核心方法控制任务状态:
done()
:绑定成功回调(类似then()
)。fail()
:绑定失败回调。progress()
:绑定进度回调。
它的设计灵感来源于 Promises/A+ 规范,但更早被 jQuery 实现。可以将其想象为一个快递包裹的追踪系统:
resolve()
表示包裹已送达(任务成功)。reject()
表示包裹退回(任务失败)。progress()
则是物流信息的实时更新(任务进度)。
1.2 Deferred 的生命周期
一个典型的 Deferred
对象生命周期如下:
const deferred = $.Deferred();
// 模拟异步任务(如 AJAX 请求)
setTimeout(() => {
deferred.resolve("任务完成!"); // 触发成功回调
}, 1000);
// 绑定回调
deferred.done((result) => console.log(result)); // 输出:任务完成!
当任务需要分阶段执行时,progress()
就派上用场了。例如,上传一个大文件时,服务器可以分批次返回已上传的字节数,而 progress()
可以实时接收这些数据。
二、deferred.progress() 方法详解
2.1 方法语法与参数
deferred.progress()
的基本语法如下:
deferred.progress( progressCallback );
- 参数:
progressCallback
:一个函数,接收进度相关的参数。这些参数由notify()
方法触发时传递。
2.2 如何触发进度事件?
要让 progress()
监听到事件,必须在异步任务中主动调用 deferred.notify()
。例如:
const deferred = $.Deferred();
// 模拟分阶段任务
setTimeout(() => {
deferred.notify("已加载 30%"); // 触发 progress 回调
setTimeout(() => deferred.notify("已加载 70%"), 500);
setTimeout(() => deferred.resolve("完成!"), 1000);
}, 1000);
// 绑定进度回调
deferred.progress((progress) => {
console.log("进度更新:", progress); // 输出两次:30% 和 70%
});
2.3 与 done/fail 的对比
方法 | 用途 | 触发条件 |
---|---|---|
deferred.done() | 处理任务成功后的逻辑 | deferred.resolve() |
deferred.fail() | 处理任务失败后的逻辑 | deferred.reject() |
deferred.progress() | 监听任务执行中的进度 | deferred.notify() |
关键区别:
done
和fail
是终态回调,仅在任务结束时触发一次。progress
是中间态回调,可多次触发,提供动态反馈。
三、实际案例:文件上传进度条
3.1 案例背景
假设需要实现一个文件上传功能,并在页面中显示实时进度条。传统方式可能需要轮询服务器或依赖原生 XMLHttpRequest
的 upload
事件,而 Deferred
可以简化这一过程。
3.2 代码实现
步骤 1:创建 Deferred 对象并模拟上传
const deferred = $.Deferred();
// 模拟异步上传过程
function uploadFile() {
let progress = 0;
const interval = setInterval(() => {
progress += 20; // 每 500ms 进度 +20%
deferred.notify(progress); // 触发进度事件
if (progress >= 100) {
clearInterval(interval);
deferred.resolve("文件上传成功!");
}
}, 500);
}
步骤 2:绑定进度与完成回调
deferred.progress((currentProgress) => {
const progressBar = document.getElementById("progress-bar");
progressBar.style.width = `${currentProgress}%`;
progressBar.textContent = `${currentProgress}%`;
});
deferred.done(() => {
alert("上传完成!");
});
步骤 3:HTML 结构与触发上传
<button onclick="uploadFile()">开始上传</button>
<div id="progress-bar" class="progress-container"></div>
<style>
.progress-container {
width: 100%;
height: 20px;
background: #ddd;
position: relative;
}
#progress-bar {
background: #4CAF50;
height: 100%;
transition: width 0.3s;
text-align: center;
line-height: 20px;
color: white;
}
</style>
3.3 运行效果
点击“开始上传”按钮后:
- 每 500ms 触发一次
notify()
,更新进度条宽度和文本。 - 当进度达到 100% 时,
resolve()
触发成功提示。
四、进阶技巧与常见问题
4.1 多次绑定 progress 回调
可以为同一个 Deferred
对象绑定多个 progress
回调,它们会按绑定顺序依次执行:
deferred.progress((p) => console.log("回调1:", p));
deferred.progress((p) => console.log("回调2:", p));
// 输出:
// 回调1: 30%
// 回调2: 30%
4.2 在 Promise 链中使用
通过 then()
方法,可以将 progress
回调整合到 Promise 链中:
deferred.then(null, null, (progress) => {
// 第三个参数是进度回调(需浏览器支持)
console.log("链式进度:", progress);
});
4.3 常见问题
问题 1:进度事件未触发?
- 确保在异步任务中调用了
deferred.notify()
。 - 检查回调是否绑定在
notify()
之前。
问题 2:如何传递多个参数?
可以通过数组传递参数,回调函数接收所有参数:
deferred.notify("文件", 75, "MB/100MB"); // 传递三个参数
deferred.progress((name, percent, detail) => {
console.log(`${name} ${percent}% (${detail})`);
});
五、结论:掌握进度控制的艺术
通过 deferred.progress()
方法,开发者可以轻松实现动态反馈机制,提升用户体验。无论是文件上传、数据加载还是后台任务,这一方法都能让界面与用户保持“同频”。
关键总结:
- Deferred 对象是管理异步任务的“总控台”,而
progress()
是它的“进度传感器”。 - 多次触发和多回调绑定让进度控制灵活且强大。
- 实际案例(如上传进度条)能直观展示其价值。
建议读者在真实项目中尝试实现类似功能,并探索 Deferred
与其他 jQuery 方法(如 $.ajax()
)的结合使用。通过实践,您将更深入理解异步编程的优雅之处!
通过本文,我们不仅掌握了 jQuery deferred.progress() 方法
的核心用法,还通过案例与技巧,为读者提供了可直接应用的解决方案。这一方法不仅是代码优化的利器,更是提升用户感知的关键工具。