ajax导致服务端线程粘滞,解决js ajax同步请求造成浏览器假死的问题
一、问题的起因
今天做一个需求遇到了这么个情况,就是用户个人中心有个功能,点击按钮,可以刷新用户当前的积分,这个肯定需要使用到ajax的同步请求了,当时喀喀喀三下五除二写玩了,大概代码如下:
/**
* 异步当前用户积分 by zgw 20161216
* @return {[type]} [description]
*/
function flushIntegralSum() {
//点击按钮刷新前修改按钮的文案,已经去掉点击事情,防止多次点击
$("#flushbutton").replaceWith('正在刷新');
$.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('刷新积分');
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('正在刷新');
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('刷新积分');
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同步请求造成浏览器假死的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。
ajax导致服务端线程粘滞,解决js ajax同步请求造成浏览器假死的问题相关推荐
- js样式会影响ajax,js ajax同步请求造成浏览器假死的问题
今天写了一个简单的loading效果,希望在点击加载按钮后会出现loading字样,然后执行ajax同步请求,加载完之后loading样式消失,本来是很简单的需求,结果遇上了很尴尬的问题~ 问题:当我 ...
- Dubbo学习记录(十五) - 服务调用【一】-之 服务端Netty的hander包装过程与 服务端线程模型
Dubbo服务调用 之前写十几篇文章, 自己对Dubbo的运行有了一定的了解.而Dubbo服务调用则是重中之重, 目测将这个过程写出来起码需要5-6篇文章: 服务端Netty的hander包装 服务导 ...
- setTimeout 导致的浏览器假死
setTimeout 导致的浏览器假死 问题 前几天,同事遇到一个浏览器假死的问题.就是浏览器在响应一个请求的时候,就突然不响应时间,进入假死状态,Cup也飙升到100%. 但是这个问题只出现在I ...
- 计算机出现假桌面怎么解决办法,win10系统apphangxprocb1引起桌面假死怎么解决【图文】...
电脑死机怎么办?有win10系统用户反应win10系统apphangxprocb1引起桌面假死怎么解决?出现这种情况该怎么解决?下面就将方法分享给大家. 描述: 出现了一个问题,该问题导致了此程序停止 ...
- java 线程耗尽_关于线程耗尽导致请求超时系统假死
线程耗尽:我们知道java程序中,所有计算都是通过线程来执行的,同时我们为了能够重复利用线程,避免频繁创建线程而消耗资源,一般我们都使用线程池,既然是池,那就表明线程是有限的,既然是有限的就会有耗尽的 ...
- java 线程耗尽_关于线程耗尽导致请求超时系统假死的思考
线程耗尽:我们知道java程序中,所有计算都是通过线程来执行的,同时我们为了能够重复利用线程,避免频繁创建线程而消耗资源,一般我们都使用线程池,既然是池,那就表明线程是有限的,既然是有限的就会有耗尽的 ...
- 解决Qt 5程序运行时界面假死的方法
在Qt 5的GUI程序中,主线程也叫GUI线程,因为它是唯一被允许执行GUI相关操作的线程.对于一些计算量比较大的非常耗时的操作,如果放在主线程中,就是出现界面无法响应的问题.这种问题的解决一种方式是 ...
- gluster集群服务器IP地址更改后导致服务无法启动的一个解决方法
问题描述 原先建立了一个3主机的gluster集群,每个机器上包含2个bricks,总共6个bricks,采用4data加2EC的数据存放架构.某天实验室路由配置改变了,原先的三个主机IP全部发生变化 ...
- Zookeeper服务端线程分析(单机)
Zookeeper单机模式下启动类为ZooKeeperServerMain#runFromConfig, 调用过程可参考:http://naotu.baidu.com/file/2... ZooKee ...
- ajax异步超时,AjaxPro实现异步调用,解决浏览器假死及超时问题(示例代码)
平时使用AjaxPro的时候基本上非常easy var msg = UseClass.Method(argument).value; 由于后台响应比較慢,所以加了个"loading" ...
最新文章
- OKR的实施案例:OKR不需要很复杂
- 发现一款3D 打印的pcDuino外壳
- c 正则表达式替换html,正则表达式替换html元素属性的方法
- Liunx操作系统的引导过程(系统操作引导过程,模拟MBR,GRUB故障,root密码遗忘解决,优化启动过程 ,运行级别的分类)
- 单例模式:Instance
- GraphQL报错:error: NetworkError when attempting to fetch resource.
- html设置table border,用css来设置table的border
- 微服务跨数据库联合查询_MySQL数据库联合查询
- 解决jquery调用NET webservice跨域的问题
- 我对类和结构的一点理解
- java实现 mysql导入_怎么用java实现mysql数据库的导入导出
- Android WIFI功能——WifiManager
- 3-arm裸机存储器控制器之SDRAM
- 荐书 | 8 本热门 AI 原版好书,趁假期充电!
- 鱼鱼Chen之学写自己的apk(六)ListView带动画图标
- NVT和minimize问题
- bzoj4716: 假摔
- hbase常见问题及解决方案总结(一)
- 如何使用COleDateTime类获取昨天(前几天)的日期
- 开始使用KMIP4J