最近做一个项目,遇到了一个问题同步ajax引起的ui线程阻塞问题,下面把我的问题解决过程分享给大家。

事情起因是这样的,因为页面上有多个相似的异步请求动作,本着提高代码可重用性的原则,我封装了一个名为getData的函数,它接收不同参数,只负责获取数据,然后把数据return。基本的逻辑剥离出来是这样的:

function getData1(){

var result;

$.ajax({

url : "p.php",

async : false,

success: function(data){

result = data;

}

});

return result;

}

这里的ajax不能用异步的,否则函数返回时,result还未赋值,会出错。所以我加了async:false。看起来好像没什么问题。我调用这个函数可以正常的得到数据。

$(".btn1").click(function(){

var data = getData1();

alert(data);

});

接下来,要加另外一个功能,由于ajax请求有一定的耗时,所以我需要在发出请求前页面有个loading效果,即显示一张“正在加载”的gif图片,想必大家也都见过。所以我的处理函数就变成了这样:

$(".btn1").click(function(){

$(".loadingicon").show();

var data = getData1();

$(".loadingicon").hide();

alert(data);

});

请求之前显示loading图片,请求完成后把它隐藏。看起来也没什么问题。为了看清效果,我的p.php代码sleep了3秒,如下:

但是我运行的时候问题出现了,我点击按钮并未像预想的那样出现这个loading图片,页面什么反应也没有。排除良久找到了原因,就在async:false这里。

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

setTimeout解决阻塞问题

既然明白了问题在哪里,我们就来针对性想办法。为了不让同步ajax请求阻塞线程,我想到了setTimeout,把请求的代码放到sestTimeout中,让浏览器重启一个线程来操作,不就解决问题了吗?于是乎,我的代码就变成了这样:

$(".btn2").click(function(){

$(".loadingicon").show();

setTimeout(function(){

$.ajax({

url : "p.php",

async : false,

success: function(data){

$(".loadingicon").hide();

alert(data);

}

});

}, 0);

});

setTimeout的第二个参数设为0,浏览器会在一个已设的最小时间后执行。不管三七二十一先运行起来看看。

结果loading图片显示出来了,但是!!!图片怎么不动呢,我明明是一张动态gif图。这个时候我很快就想到了,虽然同步请求延迟执行了,但是它执行期间还是会把UI线程给阻塞。这个阻塞相当牛逼,连gif图片都不动了,看起来像一张静态图片一样。

结论很明显,setTimeout治标不治本,相当于把同步请求“稍稍”异步了一下,接下来还是会进入同步的噩梦,阻塞线程。方案失败。

是时候用Deferred了

于是我用Deferred对象改写了代码,如下:

function getData3(){

var defer = $.Deferred();

$.ajax({

url : "p.php",

//async : false,

success: function(data){

defer.resolve(data)

}

});

return defer.promise();

}

$(".btn3").click(function(){

$(".loadingicon").show();

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

$(".loadingicon").hide();

alert(data);

});

});

可以看到我在ajax请求中去掉了async:false,也就是说,这个请求又是异步的了。另外请注意success函数中的这一 句:defer.resolve(data),Deferred对象的resolve方法可传入一个参数,任意类型。这个参数可以在done方法中拿到, 所以我们异步请求来的数据就可以以这样的方式来返回了。

至此,问题得到了解决。Deferred对象如此强大且方便,我们可以好好利用它。

我的全部测试代码如下,有意的同学可以拿去测一下:

async:false

setTimeout

deferred

ps:$.ajax的参数描述

参数 描述

url 必需。规定把请求发送到哪个 URL。

data 可选。映射或字符串值。规定连同请求发送到服务器的数据。

success(data, textStatus, jqXHR) 可选。请求成功时执行的回调函数。

dataType

可选。规定预期的服务器响应的数据类型。

默认执行智能判断(xml、json、script 或 html)。

ajax请求会阻塞dom,Jquery ajax 同步阻塞引起的UI线程阻塞问题_jquery相关推荐

  1. jQuery ajax请求两次问题,jquery ajax请求了两次问题

    页面有一个请求form: 订单编号 用户帐户 发货状态 请选择 未发送 已发送 查询 JavaScript请求部分: function showdatalist() { var username = ...

  2. ajax请求返回json实例,Jquery Ajax 学习实例2 向页面发出请求 返回JSon格式数据

    一.AjaxJson.aspx 处理业务数据,产生JSon数据,供JqueryRequest.aspx调用,代码如下: protected void Page_Load(object sender, ...

  3. ajax请求获取服务器数据,jquery.ajax发布从app引擎服务器获取数据的请求

    为noob问题道歉...... 您好,如何使用jQuery.ajax从appengine服务器的Python端获取数据?我知道如何使用ajax和适当的处理程序将数据发送到服务器,但我想知道是否有人可以 ...

  4. ajax请求php保存数据格式,jQuery ajax与php进行数据交互(数据格式问题)

    近期涉及到 jquery 开发,因此对jQuery做了一些初步的学习,jquery功能相对比较强大些,尤其是对ajax支持,jquery ajax与服务器交互,这种搭配使得"局部刷新,异步更 ...

  5. jQuery同步Ajax带来的UI线程阻塞问题及解决办法

    俗话说不作死就不会死,今天作死了一回,写了一个比较二逼的函数,遇到了同步Ajax引起的UI线程阻塞问题,在此记录一下. 事情起因是这样的,因为页面上有多个相似的异步请求动作,本着提高代码可重用性的原则 ...

  6. jq中法可以发起ajax请求的方法有,jQuery实现监控页面所有ajax请求的方法

    本文实例讲述了jQuery实现监控页面所有ajax请求的方法.分享给大家供大家参考,具体如下: 你是不是有遇到这样的问题:页面发起两个ajax请求,希望它们都成功以后,再做一个动作? 很容易想到的解决 ...

  7. Ajax设置超时时长,jquery ajax超时设置

    var ajaxTimeoutTest = $.ajax({ url:'',  //请求的URL timeout : 1000, //超时时间设置,单位毫秒 type : 'get',  //请求方式 ...

  8. html ajax请求怎么用,如何使用ajax,ajax请求的五个步骤

    有很多童鞋,在WEB前端面试的时候,常会被Ajax问题难住,其实Ajax没有你们理解的那么难,现在源码时代H5学科讲师带着大家重新来回顾一下知识点:随便再给大家普及一下小常识,今天咱们聊的就是怎么快速 ...

  9. flask ajax 上传 图片,flask jQuery ajax 上传文件

    1.html 代码 注:1.html 部分主要是一个form表单,其中表单的enctype = "multipart/form-data" 必须要有. 2.由于我的页面背景颜色设置 ...

最新文章

  1. 2022-2028年中国养老保险行业深度调研及投资前景预测报告
  2. 万变不离其宗之海量数据下的算法问题处理思路
  3. python中怎么表示整数的点称为整点_智慧职教云课堂APPPython程序设计基础答案公众号...
  4. Springboot注册Servlet
  5. CCIE-LAB-第十一篇-DMVPN+IPSEC+BGP
  6. 2019 ACM/ICPC 南昌站 G,拉格朗日插值
  7. 一些值得注意的算法题——队列、栈
  8. 转:Linux 僵尸进程详解
  9. 手机 debian linux,Android上的Ubuntu Debian Armel
  10. 7-6 What is a computer? (5 分)
  11. stm32气压传感器 带探头的_几种常用传感器
  12. 常用安防软件,Onvif,RSTP客户端 , 小工具
  13. 发货100全功能网站系统源码
  14. 【解决方案 二十五】如何对Excel表数据进行彻底转置
  15. 解决了这7个问题,我的产出效率提升了100%
  16. mysql perl教程_使用 Perl 的 MySQL 事务
  17. MacOS-Mac开发和iOS开发的区别
  18. 智安网络丨居安思危·洞见未来 — — 智安网络安全周报
  19. VScode终端配置bash.git(默认),terminal.integrated.shell:windows路径查找不到前提下
  20. tf.less(x,y)

热门文章

  1. Android Studio Error:Connection timed out: connect.解决方案
  2. Java中的SoftReference和WeakReference有什么区别?
  3. 全国二级 mysql有用_2020年全国计算机二级MySQL复习知识点:调整服务器
  4. python 微服务 etcd_python etcd api
  5. jQuery天猫商品分类导航菜单
  6. js将秒转化成时间格式
  7. JavaScript:堆栈溢出内存泄漏
  8. 中职计算机专业建设构想,《关于技能大赛引导中职计算机专业建设的思考原稿》...
  9. 如何调试程序的 Release 版本
  10. 零基础学Python可以学会吗?