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.

posted @ 2017-02-21 10:48  EdwinChan  阅读(3334)  评论(0编辑  收藏  举报