• 记处理进度条的那些事


            现有一文件,需要显示其进度状态,涉及到调用c++底层的exe,然后与c++ 进行 socket 通信获取返回值,其中包含进度

            处理逻辑:   前端界面写入一笔数据,服务中线程一进行监听,(更改数据状态后)并调用exe,另一线程监听Socket 返回值,根据关键字解析后将进度更新其中,最后web前端按照固定时间去表中读取进度后赋值给UI即可。

            

    <body>
        <script>
            $(function () {
                var ccont = 0;
                var ttpPos = "0";
                var subPos = "";
                var loadvideo = 0;
                function subViddeoCall(id,videoId) {
                    var taskid = '@ViewBag.taskid';
                    var videoId = videoId;
                    if (subPos != "-1" && subPos != "100") {                   
                        //按照进度-截取视频操作
                        $.post("../Kiaser/QuertTaskPartProgress", { Id: id }, function (data) {
                            if (data != null) {
                                subPos = data.Pos == null ? "0" : data.Pos;
                                //判断当前进度停留时间
                                //CountMinuDate(taskpos, ttpPos, videoId, taskid)
                                //ttpPos = subPos;
                                $("#prog").val(subPos).show();
                                $("#spe").html(subPos + "%").show();
                            };
                        }, "JSON");
                    }
                    if (subPos == "-1") {
                        //截取失败
                        loadvideo = 0;
                        subPos = "0";
                        //停止循环
                        clearInterval(sub);
                        //刷新列表
                        SubVideoFail(videoId, taskid);
                    }
                    if (subPos == "100") {
                        loadvideo = 0;
                        subPos = "0";                  
                        //$.ajaxSettings.async = false;
                        $.post("../Kiaser/UpdateUploadType", { value: 9, videoId: videoId, taskId: taskid }, function (data) {
                            //刷新视频列表状态
                            VideoStatus();
                            //关闭进度条
                            $("#prog").val(0).hide();
                            $("#spe").html("");
                            clearInterval(sub);
                        }, "JSON");
                        //$.ajaxSettings.async = true;
    
                    }
                }
    
                var sub;
                $("#btnGetPos").click(function () {
                    //先执行一次
                    subViddeoCall(id, videoId);
                    //循环取值3000
                    sub = setInterval(subViddeoCall, 3000, id, videoId);
                });
            })
    
        </script>
    
        <div>
            <span>进度</span>
            <progress max="100" value="0" id="prog" style="display:none"></progress>
            <span id="spe"></span>
        </div>
        
        <input type="button" id="btnGetPos" value="获取进度"/>
    </body>

    单一刷进度的话,没啥,就是将进度值付给 progress  标签的 value属性值(HTML5),然后判断进度值,不为-1到100 则查询并赋值,为-1则失败,为100则成功,这里需要注意的是要把进度值为 [1,100) 的赋值写在最前面,因为ajax 是异步的,如果写在后面的话,会出现进度异常,除非把赋值的ajax 改成同步 ($.ajaxSettings.async = false; ajax .... ; $.ajaxSettings.async = true;),这是一个坑.

           还要考虑一种情况, 比如进度正在刷新时,服务突然停止或者资源沾满等原因,进度则会长时间停留在某一固定值中,体验感很差。这是就需要设置一个时间点,来计算当前进度和上一次进度如果一样,则开始计时,超过一定时间仍然一样,则判断当前任务执行失败。于是做了如下处理

                //计算时间差  当前进度/上一次进度/文件Id/任务Id
                function CountMinuDate(taskpos, tpPos, videoId, taskid) {
                    if (taskpos == tpPos) {
                        ccont += 1;
                        console.log("当前进度:" + taskpos + " 上次进度:" + tpPos + " 执行次数:" + cont + " 类型:" + typeof (cont));
                        if (ccont == 10) {
                            console.log("任务执行失败");
                            //重复次数清零
                            ccont = 0;
                            //调用失败方法
                            Fail(videoId, taskid);
                        }
                    }
                    else {
                        //重复次数清零
                        ccont = 0;
                    }
                }

    这里当出现当前进度和上次进度相同时,调用此方法,并计算次数,注意,如果不相同,需要清零计数变量,同样在超过3秒后(10*3000),计数变量仍然需要清零。然后在之前的获取进度的方法体中调用此方法即可。

                 if (subPos != "-1" && subPos != "100") {                   
                        //按照进度-截取视频操作
                        $.post("../Kiaser/QuertTaskPartProgress", { Id: id }, function (data) {
                            if (data != null) {
                                subPos = data.Pos == null ? "0" : data.Pos;
                                //判断当前进度停留时间
                                CountMinuDate(taskpos, ttpPos, videoId, taskid)
                                ttpPos = subPos;
                                $("#prog").val(subPos).show();
                                $("#spe").html(subPos + "%").show();
                            };
                        }, "JSON");
                    }

    至于用在项目中的话,肯定还需要考虑正在刷新进度的时候,关闭界面,然后在重新进来,这时,需要在界面时初始化的时候,多加一个判断,是否有任务,若有,先查询进度值,或正常,或失败,或完成。根据不同的状态值,再执行各自的方法即可

            

  • 相关阅读:
    通过递归展示树状结构
    Description Resource Path Location Type Failure to transfer org.apache.maven.plugins:maven-surefire-
    Entity与Entity之间的相互转化
    java 记录数据持续变化时间
    Springmvc 异常处理
    Spring Validation 验证
    Jmeter的操作流程
    Python基础字符串前加u,r,b,f含义
    linux连接Windows系统之项目连接
    Jmeter 连接远程测压__(负载测试)
  • 原文地址:https://www.cnblogs.com/Sientuo/p/10791941.html
Copyright © 2020-2023  润新知