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

 更新时间:2018年01月18日 15:17:52   作者:来自潘大大  
下面小编就为大家分享一篇解决js ajax同步请求造成浏览器假死的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

一、问题的起因

今天做一个需求遇到了这么个情况,就是用户个人中心有个功能,点击按钮,可以刷新用户当前的积分,这个肯定需要使用到ajax的同步请求了,当时喀喀喀三下五除二写玩了,大概代码如下:

/**
  * 异步当前用户积分 by zgw 20161216
  * @return {[type]} [description]
 */
 function flushIntegralSum() {
     //点击按钮刷新前修改按钮的文案,已经去掉点击事情,防止多次点击
  $("#flushbutton").replaceWith('<a style="color:#3fb0ff;font-size:14px;" href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="flushbutton">正在刷新</a>');
  $.ajax({
   url:'URL',
   type:'post',
   async:false,
   // data:{},
   success:function(json){
    json = eval('('+json+')');
    if(json.url){window.location.href=json.url;return;}
    $("#flushbutton").replaceWith('<a style="color:#3fb0ff;font-size:14px;" href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" onclick="flushFreeSum();" id="flushbutton">刷新积分</a>');
    if(json.code!=1){
     alert(json.msg);
    }else{
     $("#free_sum").html(json.free_sum);
    }
    return;
   }
  });
 }

本以为这么简单的功能喀喀喀随便写写就没事了,在运行的时候出现了问题,当用户点击刷新积分按钮时,文案没有修改为"正在刷新",但是ajax请求发送了,于是我查看网页代码,发现js其实把文案和html元素绑定的onclick事件去掉了,在请求成功后有变回原来的了,但是页面上边文案没有改变,当时很奇怪,不知道为什么html代码里边改变了,页面却没有变点变化

二、了解问题原因

问题的根源:当时我进行了排查,最后发现是 "async:false" 的问题,换成异步的就没有问题了,那为什么同步请求会产生代码失效的问题呢?

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

三、解决问题

1.我当时使用了 setTimeout 来解决,把ajax代码放在sestTimeout中,让浏览器重启一个线程来操作,这样就解决问题了,代码如下:

function flushIntegralSum() {
     //点击按钮刷新前修改按钮的文案,已经去掉点击事情,防止多次点击
  $("#flushbutton").replaceWith('<a style="color:#3fb0ff;font-size:14px;" href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="flushbutton">正在刷新</a>');
  setTimeout(function(){
   $.ajax({
    url:'URL',
    type:'post',
    async:false,
    // data:{},
    success:function(json){
     json = eval('('+json+')');
     if(json.url){window.location.href=json.url;return;}
     $("#flushbutton").replaceWith('<a style="color:#3fb0ff;font-size:14px;" href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" onclick="flushFreeSum();" id="flushbutton">刷新积分</a>');
     if(json.code!=1){
      alert(json.msg);
     }else{
      $("#free_sum").html(json.free_sum);
     }
     return;
    }
   });
  },0) 
 }

setTimeout的第二个参数设为0,浏览器会在一个已设的最小时间后执行

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

2.使用 Deferred 来解决

以上这篇解决js ajax同步请求造成浏览器假死的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • JS随机生成不重复数据的实例方法

    JS随机生成不重复数据的实例方法

    这篇文章介绍了JS随机生成不重复数据的实例方法,有需要的朋友可以参考一下
    2013-07-07
  • jsvascript图像处理—(计算机视觉应用)图像金字塔

    jsvascript图像处理—(计算机视觉应用)图像金字塔

    上一篇文章,我们讲解了边缘梯度计算函数,这篇文章我们来了解图像金字塔;图像金字塔被广泛用于计算机视觉应用中;图像金字塔是一个图像集合,集合中所有的图像都源于同一个原始图像,而且是通过对原始图像连续降采样获得的
    2013-01-01
  • form表单中去掉默认的enter键提交并绑定js方法实现代码

    form表单中去掉默认的enter键提交并绑定js方法实现代码

    form表单中默认的enter提交是不是让你已经很耐烦了吧,本文主要讲解一下如何去掉默认的enter键提交同时绑定js方法,感兴趣的朋友可以参考下哈
    2013-04-04
  • js操作CheckBoxList实现全选/反选(在客服端完成)

    js操作CheckBoxList实现全选/反选(在客服端完成)

    对于CheckBoxList控件来说,一方面要实现大量数据在服务器端的绑定工作,另一方面往往要求实现全选、反选等功能,接下来将介绍js操作CheckBoxList实现全选/反选,感兴趣的朋友可以了解下,或许对你有所帮助
    2013-02-02
  • javascript的alert box在java中如何显示多行

    javascript的alert box在java中如何显示多行

    这篇文章主要介绍了javascript的alert box在java中如何显示多行,需要的朋友可以参考下
    2014-05-05
  • JS自定义滚动条效果

    JS自定义滚动条效果

    这篇文章主要为大家详细介绍了JS自定义滚动条效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • 原生js实现随机点名

    原生js实现随机点名

    这篇文章主要为大家详细介绍了原生js实现随机点名,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • JavaScript按位运算符的应用简析

    JavaScript按位运算符的应用简析

    下面根据自己的认知简单的谈一下js中的位操作使用(同样适用于其他语言),如果有错误,欢迎指正
    2014-02-02
  • 深入理解Webpack 中路径的配置

    深入理解Webpack 中路径的配置

    这篇文章主要给大家介绍了关于Webpack2中路径配置的相关资料,文中介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-06-06
  • 微信小程序“摇一摇”的实例代码

    微信小程序“摇一摇”的实例代码

    微信小程序并没有提供摇一摇API接口,但是提供了一个重力感应的API,接下来我们可以用这个方法来模拟微信摇一摇功能,具体实现代码,大家参考下本文
    2017-07-07

最新评论