Flask-python-前端实时显示后端处理进度

目录

   前言
   0. 目录结构
   1. Python 后端进度条-交互逻辑
   2. Python 后端进度条-前端代码
     2.1 download.html
     2.2 javascript 代码实现 (主要功能
     2.3 Python 后端进度条-后端逻辑代码
   3. 注意事项
   4. 总结

前言

回到顶部👆

   今天上班时,突然有人在群里问前端如何实时显示后端处理进度的问题,想了想觉得挺有意思,于是网上看看材料,自己简单的实践了一个以做学习记录。
0. 目录结构

回到顶部👆


1. Python 后端进度条-交互逻辑

回到顶部👆

思路:
   1. 点击页面的“展示进度条测试数据”按钮button,向后台发送数据处理请求;
   2. 后台处理数据: process_data,做主要的业务逻辑处理(示例仅简单显示循环数);
   3. 后台展示数据: show_progress,通过一个接口过去上一步接口设置的公共变量值;
   4. 前端根据后台的处理进度实时更新进度条。
   此程序 的负载主要集中在前端,所以对后端的负载很小.


2. Python 后端进度条-前端代码

回到顶部👆

2.1 download.html

回到顶部👆

   Html页面用boostrap的进度条, 进度条由2个div嵌套而成,修改内层div的width可以更新进度

<!DOCTYPE html>
<html lang='en'>
<head>
    <meta charset='UTF-8'>
    <title>进度条</title>
    <script src='/static/js/jquery-3.3.1.min.js'></script>
    <style>
        .progress-div{
            background: rgba(0, 0, 0, 0.03);
            width: 1000px;
            height: 140px;
            padding: 60px 20px;
            visibility: hidden;
        }
        .progress{
            margin: 0;
            width: 100%;
        }
    </style>
</head>
<body>
    <div class="container">
        <!--1. 按钮-->
        <button class="btn btn-default" type="button">展示进度条测试数据</button>
        <button class=‘’btn btn-default‘’ type=‘’button‘’>重新展示
	    <!--2. 进度条-->
	    <div  class="progress-div">
	        <div class="progress">
	            <div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="min-width: 2em; width: 2%;">2%
	            </div>
	        </div>
	    </div>
    </div>
</body>
2.2 javascript 代码实现 (主要功能)

回到顶部👆

   在这里边可以看到在更新前端界面的时候设置 0.5秒钟去更新后台的数据.这个地方因为测试的数据特别快,在正常的业务中可以根据实际情况设置.

  1. 首先为按钮button绑定点击事件click
  2. 在click事件中设置一个setInterval函数,用于持续请求后台进度,不断更新进度条;
  3. 向后台发送数据处理请求,当该请求成功返回后结束setInterval函数,并更改进度条样式。
    由于setInterval和getJSON的回调函数都是异步执行,这里就相当于做了个登记,将任务加入队列。
    代码如下:
<script>
// 生成随机uuid(防止多用户请求进度条混乱)
function guid(){
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy/]g, function(c){
        var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
        return v.toString(16);
    });
}

$(function () {
        $('.btn').on('click', function () {
                // 生成唯一的uuid
                var uuid = guid();
                // 设置定时器,隔段时间请求一次数据
                var sitv = setInterval(function(){
                    // prog_url指向请求进度的url,后面会在flask中设置
                    var prog_url = '/show_progress/' + uuid
                    $.getJSON(prog_url, function(num_progress){
                        $('.progress-div').css('visibility', 'visible');
                        $('.progress-bar').css('width', num_progress.res + '%');
                        $('.progress-bar').css('background', 'green');
                        $('.progress-bar').css('text-align', 'center');
                        $('.progress-bar').text(num_progress.res + '%');
                    }); 
                }, 500);                              
            // 点击事件第一个请求地址,发送请求,后台业务开始执行  
            var this_url = '/progress_data/' + uuid                     
            $.getJSON(this_url, function(res){
                // 清楚定时器
                cleanInterval(sitv);
                if(res.res != null){
                    $('.progress-bar').css('width', '100%');
                    $('.progress-bar').text('100%');
                    setTimeout(function(){
                        alert('下载成功!');
                    }, 100);
                }else{
                    $('.progress-bar').css('background', 'red');
                    setTimeout(function(){
                        alert('失败了!');
                    }, 1);
                }
            });
        })
}) 
</script>
2.3 Python 后端进度条-后端逻辑代码

回到顶部👆

   我这里使用的后端为Flask, 使用别的后端思路相当。
manage.py:

from flask import Flask, jsonify, render_template

app =  Flask(__name__)

# 存储进度数据
progress_data = {}

@app.route('/')
def index():
    '''
    展示主页面
    '''
    return render_template('download.html')

@app.route('/progress_data/<uuid>')
def progress_data(uuid):
    '''
    通过uuid将数据存入变量progress_data
    '''
    for i in range(12345666):
        num_progress = round(i * 100 / 12345665, 2)
        progress_data[uuid] = num_progress
    return jsonify({'res': num_progress})

@app.route('/show_progress/<uuid>')
def show_progress(uuid):
    '''
    前端请求进度的函数
    '''
    return jsonify({'res': progress_data[uuid]})

if __name__ = '__main__':
    app.run(host='127.0.0.1', port=8013, debug=True)

3. 注意事项

回到顶部👆

  1. 使用alert是需要注意,会阻塞js主线程,然后才会渲染页面(那些改变css等等语句),或者将alert放入setTimeout中延迟执行。
  2. 如果同时发起多个请求(1个以上页面不同时间点击button),由于前端请求的是后端设置的全局变量,所以会出现进度条混乱,解决方法就是前端每次请求都带上一个唯一标示的uuid,后端设置公共变量时可以以uuid为键,进度为值。
  3. 注意在download.html的head标签中引入jquery.js,否则使用$时会报错。

4. 总结

回到顶部👆

总的思路如下:
   当用户点击了展示进度条按钮,前端页面的js代码开始工作,先向后端progress_data发送业务处理请求,同时设置一个定时器,这个定时器会按照一定频率请求后端另外一个接口(show_progress),在后端的show_progress接口中返回了一个公共变量progress_data的值(一个百分比),这个变量的值是由接口progress_data设置进去的,当接口progress_data完成了业务(比例为100%),此时前端调用的接口progress_data才会有返回值,然后根据这个返回值提示用户进度条展示成功与否。

注意:
   无论成功失败,计时器一定要记得清除掉;


完整代码下载:progress_demo.zip

  • 12
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
Flask中实现前端实时显示后端处理进度可以通过使用WebSocket技术来实现。WebSocket是一种基于TCP的协议,可以实现双向通信,使得前后端能够在同一个连接上进行实时数据交换。 首先,我们需要在Flask中使用WebSocket,可以使用Flask-SocketIO来方便地实现WebSocket功能。安装Flask-SocketIO后,我们可以在Flask应用中使用socketio对象来实现WebSocket的功能。 在后端代码中,我们可以通过在任务处理函数中发送进度信息给前端。例如,我们可以在任务处理函数的循环中,使用socketio的emit函数发送当前任务的进度信息。前端页面将通过监听WebSocket消息的方式接收进度信息。 在前端代码中,我们需要在页面中引入SocketIO的JavaScript库,并创建一个SocketIO对象。然后,我们可以使用socket.on()函数来监听后端发送的进度信息,并根据接收到的进度信息来更新前端页面上的进度显示。 需要注意的是,为了防止过多的WebSocket连接导致性能问题,我们可以考虑使用Flask-SocketIO提供的命名空间和房间功能。通过使用命名空间和房间,我们可以将客户端分组,只向特定的客户端发送进度信息。 总结起来,实现Flask前端实时显示后端处理进度的关键步骤是:在Flask应用中使用Flask-SocketIO实现WebSocket功能,后端任务处理函数中使用socketio对象发送进度信息,前端页面中使用SocketIO对象监听进度信息并更新页面显示。这样就能够实现前端实时显示后端处理进度的功能了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值