记处理进度条的那些事

        现有一文件,需要显示其进度状态,涉及到调用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");
                }

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

 

 

        

posted @ 2019-04-29 17:52  郎中令  阅读(308)  评论(0编辑  收藏  举报