js ajax同步请求造成浏览器假死的问题

今天写了一个简单的loading效果,希望在点击加载按钮后会出现loading字样,然后执行ajax同步请求,加载完之后loading样式消失,本来是很简单的需求,结果遇上了很尴尬的问题~

问题:当我点击按钮后,loading字样并没有出现,反而是先执行了ajax请求,请求完成后才出现了loading的样式~

原因:经过各种排查,咨询各方大神,发现原来问题是在于ajax同步请求。浏览器的渲染(UI)线程和js线程是互斥的,在执行js耗时操作时,页面渲染会被阻塞掉。当我们执行异步ajax的时候没有问题,但当设置为同步请求时,其他的动作(ajax函数后面的代码,还有渲染线程)都会停止下来。即使我的DOM操作语句是在发起请求的前一句,这个同步请求也会“迅速”将UI线程阻塞,不给它执行的时间

解决方式:

1.在ajax外加上setTimeout,让浏览器重启一个线程来操作。

到这里问题就解决了,但是你可以试试当你点击按钮的时候如果需要弹出一个gif图片,并且图片一直在旋转,提示更新中,你会发现图片虽然会显示,但是图片却是不动的,那是因为虽然同步请求延迟执行了,但是它执行期间还是会把UI线程给阻塞。这个阻塞相当牛逼,连gif图片都不动了,看起来像一张静态图片一样。结论很明显,setTimeout治标不治本,相当于把同步请求“稍稍”异步了一下,接下来还是会进入同步的噩梦,阻塞线程,这种方法只适合发请求之前操作简单的时间短的情况。

2.使用 Deferred 来解决(可解决gif动画不动的问题)

$('btn').click(function(){

    $('.loading').fadeIn();

    $.when(getData()).done(function(data){

        $('div').html(data);

    });

    $('.loading').fadeOut();

});

function getData(){

    var defer = $.Deferred();

    $.ajax({

        url:"xxxx.xxx",

        type:"post",

        data:{},

        async:true,//异步

        success:function(data){

            defer.resolve(data);

        }

    });

    return defer.promise();

}

这里首先创建一个deffered对象,在ajax的success函数中将ajax返回的数据保存在deffered对象中,然后返回deffered对象。这样就保证了在下一次ajax请求的时候这个ajax已经请求完成。deferred对象的好处包括它允许你给一个事件自由添加多个回调函数。或者给多个事件统一指定回调函数。

 

 

//===============此处为分割线===============

感谢大神补充,浏览器假死问题主要是js的耗时操作,导致浏览器还没来得及渲染就已经卡住了,简单举例:

            $('#btn1').click(function(){
                $('.loading-wrap').fadeIn();
                
                for(var i = 0; i < 1000000; i++){
                    console.log('假死');
                }
                
                $('.loading-wrap').fadeOut();
            });

这段按钮点击事件,同样会导致浏览器卡死,这与ajax同步请求原理造成的问题相同

转载于:https://my.oschina.net/situqixun/blog/898094

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值