• js阻塞ui进程涉及的知识点整理


    项目进行中遇到了同步ajax阻塞ui线程阻塞的问题,原因是执行两个同步ajax请求为一次完整的方法,因业务需求需要循环执行这个方法,检查后台返回的数据正确,但是由于ajax请求时间过长,考虑增加遮罩层与loading图标,

    这时遇到该问题,loading图标 .后面的出图也是所有方法执行后只出一个图

    代码类似于这样:

    $(function(){
        for(var key in data){//循环执行
           $('#mask').css('display','block');//遮罩层
           doAjax();        
           $('#mask').css('display','none');//去除遮罩层 
        }
       
    });
    
    var doAjax = {
       aAjax:function(){//第一个ajax请求
          ajax({
              async:false
              url:url,
              success:function(){
                  doAjax.bAjax();
              }
          });
        };
       bAjax : function(){//第二个ajax请求
            ajax({
                async:false
                url:url,
                success:function(){
                   doAjax.doHightCharts();
               }
            });
         };
       doHighCharts:function(){
             //出图
        }
    }    
        

    此时为每一个过程考虑两次js阻碍ui线程的加载,第一次添加遮罩层时,第二次为加载highcharts出图时.

    考虑两次的原因均因为async:false的原因.由于浏览器的渲染(UI)与与js线程是互斥的,在执行js耗时操作时,页面渲染会被阻塞掉。当我们执行异步ajax的时候没有问题,但当设置为同步请求时,其他的动作(ajax函数后面的代码,还有渲染线程)都会停止下来。即使我的DOM操作语句是在发起请求的前一句($('#mask').css('display','block');//遮罩层),这个同步请求也会“迅速”将UI线程阻塞,不给它执行的时间。这就是代码失效的原因。

    在探究这个问题时,了解到更多的知识:(由于项目工期紧,没能使用各种方法实现)

    jQuery的deferred对象

    项目中的这个难题使用最简单易懂的方式:

    setTimeout解决阻塞问题:

    var flag = {
       num:0
    }
    $(function(){
        $('#mask').css('display','block');//遮罩层
       setTimeout{//首先执行一次
           doAjax(),0        
        }
     
    });
    
    var doAjax = {
       aAjax:function(){//第一个ajax请求
          ajax({
              async:true,//可以异步
              url:url,
              success:function(){
                  doAjax.bAjax();
              }
          });
        };
       bAjax : function(){//第二个ajax请求
            ajax({
                async:true,//可以异步
                url:url,
                success:function(){
                      flag.num++;//此时执行避免异步
                        if (flag.num < data.length) {
                            setTimeout(doAjax.aAjax(), 100);
                        }
                       doAjax.doHightCharts();
                       if(flag.num==data.length){
                          $('#mask').css('display','none');//去除遮罩层
                        }
               }
            });
         };
       doHighCharts:function(){
             //出图
        }
    }    
                                                                    

    此时简单来说,setTimeout将方法排列的js执行队列的最后(哪怕设置第二个参数为0),所以说使用setTimeout是为了确保UI刷新线程不被阻塞.

    理解此过程可以根据:

    js单线程浅谈

    js线程

    在这里进行简单的总结:

    1.

    技术小白记录自己的经验与分享,不足之处多多包含,欢迎指正!
  • 相关阅读:
    Android 接口中含有" "不能正常显示
    android
    EditText禁止自动弹出键盘
    相册选择照片
    Android完美获取状态栏高度、标题栏高度、编辑区域高度的获取
    Android WebView获取UserAgent
    php extract()用法
    php的安装和破解
    php 兼容换行符
    php 引用
  • 原文地址:https://www.cnblogs.com/EdwinChan/p/6422985.html
Copyright © 2020-2023  润新知