如何实现一个前后端实时通信的进度条功能

1、需求背景
我们的产品有个下载导出成员信息表单的功能,但当数据量大的时候,处理时间较长,客户希望能有个进度条显示下载的进度,在焦急等待的时候,有个心理安慰


2、开发工具及框架
SpringBoot + Maven +JDK8


3、整体思路
数据传输的主要途径:request.session
(1)前端页面编写调试
(2)后端最短路径传输模拟数据,调试
(3)后端业务逻辑处理,传输真实数据
(4)前端操作、页面优化

👉进度条最终效果
1\点击“导入excel表格”
在这里插入图片描述

2\刚下载完
在这里插入图片描述

3\下载完2秒左右关闭进度条


1. 前端页面编写

👉进度条核心标签:progress
👉js定时器:setInterval、setTimeout


思路:
① 如果你的项目和我一样,要运行后才能打开前端页面的话,建议自己新建一个项目,把前端页面调好后,再放到原项目中
② 调试过程中,如果你的百分数直接从0到100,没有中间的数字,一定是不对的,继续调整
③ 注意判断条件添加的位置:如果你的提示语显示顺序和百分数有关,那就一定要小心谨慎了,这里很有可能弄错

(1)测试代码编写:为便于调试,我把js代码也一并写到了html页面中(以下代码浏览器打开可直接运行)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>进度调测试5</title>
    <script>
        function download() {
            var  pro=document.getElementsByTagName( "progress" )[0];
            pro.style.display = 'block';
            var progressValue = document.querySelector('#progress-value');
            progressValue.style.display = 'block';
            var value = 0;

            setInterval(function() {
                if (value < 100){
                    value++;
                    pro.value = value;
                    progressValue.innerText = value + '%';
                }else {
                    progressValue.innerText = '下载完成';
                    setInterval(function (){
                        location.replace(location.href);
                    },2000);
                }
            }, 20);
        };
    </script>
</head>
<body>
<br/>
<span id="progress-value" hidden="hidden">0</span>
<progress value= "0"  max= "100" hidden="hidden">您的浏览器不支持progress标签</progress>

<br/>
<button onclick="download()">点击下载</button>
</body>
</html>

在这里插入图片描述
在这里插入图片描述

(2)测试代码运行没问题后,挪入项目中,修改的点有:

  • 将百分数和下载提示分成了2个标签;
  • 百分数改为从request中获取数据
//html代码:

<div style="position: relative;width: 175px;height: 100%;margin-left: calc(50% - 50px);display: inline-block">
    <progress value= "0"  max= "100" hidden="hidden">
        您的浏览器不支持progress标签
    </progress>
    <span id="progress-value" hidden="hidden" style="position: absolute;top:-4px;right:5px"></span>
    <p id="progress-tips" hidden="hidden" style="text-align: center;width: 122px"></p>
</div>
//js代码:在下载按钮的点击函数中调用以下函数:

function progressBar() {
   //显示进度条、百分数、提示语
   var pro = document.getElementsByTagName("progress")[0];
   pro.style.display = 'block';
   var progressValue = document.querySelector('#progress-value');
   progressValue.style.display = 'block';
   var progressTips = document.querySelector('#progress-tips');
   progressTips.style.display = 'block';
   progressTips.innerText = '';
   var value = 0;
   //设置定时器,每隔一段时间获取requestSession中的百分数
   var time = setInterval(function () {
      $.ajax({
         async: true,
         type: 'post',
         dataType: 'json',
         url: ctx + "/member/getPercent",
         //获取百分数成功,修改相关值
         success: function (data) {
            value = data.percent;
               pro.value = value;
               progressValue.innerText = value + '%';
               progressTips.innerText = '下载中';
            //下载完成后,请求刷新百分数,并在2秒后关闭标签
            if (value == "100"){
               progressTips.innerText = '下载完成!';
               setTimeout(function (){
                  $.ajax({
                     type: 'post',
                     dataType: 'json',
                     url: ctx + "/member/flushPercent",
                     success:function (){
                           pro.style.display = 'none';
                           progressValue.style.display = 'none';
                           progressTips.style.display = 'none';
                           pro.value = 0;
                           progressValue.innerText = '';
                     }
                  });
               },2000);
               clearInterval(time);
               return ;
            }
         },
      });
   }, 10);
};

2. 前后端打通

目的:主要是测试前端是否能成功获取到后端传来的数据并展示,所以直接选取一个最短路径来传输数据,在controller中新增如下两个接口。
这里在控制台打印percent,主要是方便查看程序运行中接口的调用情况(作用很大!!!不要省略!!!)


(这时不建议大家直接将业务层计算的百分数传给前端,增加数据传输流程,如果出问题的话,排查起来更慢。但嫌麻烦的话,也可以直接跳到第3步。)

//接口一:设置并获取百分数
HashMap<String, Object> map = new HashMap<>();
  try {
  	 request.getSession().setAttribute("percent",50);
    Object percent = request.getSession().getAttribute("percent");
    map.put("percent",percent);
  } catch (Exception e) {
    e.printStackTrace();
  }
String per = JSON.toJSONString(map);
System.out.println("2、获取到的百分数为" + per);

//接口二:刷新百分数
request.getSession().setAttribute("percent",null);
Object percent = request.getSession().getAttribute("percent");
System.out.println("3、刷新百分数为" + percent);

3. 后端传输真实业务数据

第三步没问题后,我们就直接处理实际的业务逻辑啦,计算真实的百分数,并拉通数据传输的通道

(1)本项目中的进度条主要是用来体现表格的下载进度,而表格下载的主要代码逻辑就在于,将成员数据写入表格里的这个过程。所以我这里的百分数,计算的方式是:
百分数 = 当前写入成员的序号 / 总成员数 * 100;

代码如下:

//👉设置百分数
//list是成员集合

for (int i = 0; i < list.size(); i++) {
    Double percent = (i + 1) / (double)list.size() * 100;
    //这里对小数采用向下取整,例如99.5会取整为99
    percent = Math.floor(percent);
    request.getSession().setAttribute("percent",percent);
    System.out.println("1、设置百分数为" + percent);
    }

(2)修改controller的两个接口

//👉获取百分数
@ResponseBody
@RequestMapping(value = "/getPercent")
public String getPercent(HttpServletRequest request) {
    HashMap<String, Object> map = new HashMap<>();
    try {
    Object percent = request.getSession().getAttribute("percent");
    map.put("percent",percent);
    } catch (Exception e) {
       e.printStackTrace();
    }
    String per = JSON.toJSONString(map);
    System.out.println("2、获取到的百分数为" + per);
    return per;
    }
    
//👉刷新百分数
@ResponseBody
@RequestMapping(value = "/flushPercent")
public void flushPercent(HttpServletRequest request) {
    request.getSession().setAttribute("percent",null);
    Object percent = request.getSession().getAttribute("percent");
    System.out.println("3、刷新百分数为" + percent);
}

(3)运行项目,测试。调试过程中,不要忘了看控制台打印的输出语句,对排查bug很有用哦

4. 调试优化

这里主要就是前端页面的优化啦~
我这个项目里,存在以下一个关键问题:
成员信息表格下载,后端逻辑处理主要是3个部分:
(1)根据用户选择的成员,遍历到数据库中查找成员信息;
(2)将成员信息写入到表格里
(3)将表格写入到流中,导出文件
过程(1)(2)都很耗时间,然而进度条只能反映过程(2)的进度,所以过程(1)还是需要用户等待。这时前端页面的优化为:在前端页面添加相关提示,提醒用户文件正在下载。


如果你从头到这里都没调通的话,建议就先只做进度条和百分数的展示(省去提示语),减少一些前端的判断。因为前后端拉通调的话,数据传输、判断的先后等细节都可能导致成功与你擦肩而过(别问我为什么知道


最后,如果有什么没讲清楚或可以完善优化地方,欢迎一起讨论;看完有收获就点个赞吧
bye~

参考文档:
progress bar(可参考前端页面进度条的实现)
SpringBoot如何实现一个实时更新的进度条的示例代码(可参考进度条实现的整体思路)

  • 9
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 可以使用 HTML 的 ```<progress>``` 标签来实现原生的进度条。首先,在 HTML 中创建一个 ```<progress>``` 标签,并给它设置一个初始值和最大值。然后,使用 JavaScript 来更新进度条的值。下面是一个简单的示例: ```HTML <progress id="myProgress" value="0" max="100"></progress> ``` ```JavaScript var progressBar = document.getElementById("myProgress"); function updateProgress(newValue) { progressBar.value = newValue; } ``` 在这个例子中,我们通过调用 ```updateProgress(newValue)``` 函数来更新进度条的值。 另外可以使用 css 去修饰进度条的样式,例如背景颜色,大小等。 ### 回答2: 要实现一个进度条,可以使用JavaScript原生的方式操作DOM元素来实现。 首先,在HTML中创建一个包含进度条的容器元素,例如一个div元素,给它一个唯一的id,方便在JavaScript中操作。如下所示: ```html <div id="progress-bar"></div> ``` 然后,在JavaScript中获取该容器元素,并设置它的样式,包括宽度和背景颜色等,表示进度条的外观。可以使用style属性来设置样式。如下所示: ```javascript var progressBar = document.getElementById('progress-bar'); progressBar.style.width = '0%'; progressBar.style.backgroundColor = '#00FF00'; ``` 接着,定义一个函数用于更新进度条的进度。该函数的参数可以是表示进度的数值,例如进度的百分比。在函数中,通过修改进度条容器元素的宽度来改变进度条的进度。如下所示: ```javascript function updateProgressBar(progress) { progressBar.style.width = progress + '%'; } ``` 最后,在其他地方调用updateProgressBar函数,传入不同的进度值,即可实现进度条的动态更新。例如,可以使用定时器模拟进度的增长。如下所示: ```javascript var progress = 0; var timer = setInterval(function() { progress += 10; // 每次增加10% if (progress >= 100) { clearInterval(timer); // 达到100%时停止定时器 } updateProgressBar(progress); }, 1000); ``` 以上就是使用JavaScript原生实现一个简单的进度条的方法。根据需要可以进行样式、动画等更多的定制和改进。 ### 回答3: 进度条是一种常见的页面元素,可以用来显示任务的进展情况或者加载的进度。在JavaScript中,我们可以通过一些方式来实现一个进度条。 一种简单的方式是利用CSS和JavaScript的动态改变元素样式来实现进度条的效果。首先,在HTML中定义一个容器元素,作为进度条的外框。然后使用CSS样式将其设置为合适的大小、颜色和形状。接着,使用JavaScript获取任务进展的百分比,并根据百分比来改变进度条的宽度,从而显示当前任务的进展情况。 HTML部分: ```html <div id="progress-bar"></div> ``` CSS部分: ```css #progress-bar { width: 0%; height: 20px; background-color: blue; transition: width 0.5s ease-in-out; } ``` JavaScript部分: ```javascript // 获取任务进展的百分比 var progress = 50; // 假设任务已完成50% // 获取进度条元素 var progressBar = document.getElementById('progress-bar'); // 根据任务进展的百分比来设置进度条的宽度 progressBar.style.width = progress + '%'; ``` 这样,当进度为50%时,进度条的宽度会动态地改变为50%。当任务进展更新时,只需要更新`progress`的值,再次执行`progressBar.style.width = progress + '%'`来实现进度条的更新。 以上是一个简单的使用原生JavaScript实现进度条的方法,当然,如果需要更加复杂的效果和功能,可以使用一些库或框架(如Bootstrap、jQuery等)来辅助实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值