前阵子做项目,遇到一个很奇怪的问题。
我的html页面执行一个删除item的操作,需要跟后台用ajax交互。由于后台处理的过程有点长,为了给用户更好的体验,我试图在ajax请求发出前,让页面显示一个loading的gif图,当收到后台ajax处理结束的信号后,再将这个loading图隐藏。
然而,奇怪的事情发生了。 页面确实出现了那个gif图,但是却完全不动,页面出现假死的状态。
查阅了很多资料,请教了很多高手,都没有找到合适的解决方案。最后同事发来一个链接,让我照着试一试,没想到解决了问题。
http://www.alixixi.com/web/a/2014060493440.shtml
原因在ajax请求的async:false这里。
原来浏览器的渲染(UI)线程和js线程是互斥的,在执行js耗时操作时,页面渲染会被阻塞掉。当我们执行异步ajax的时候没有问题,但当设置为同步请求时,其他的动作(ajax函数后面的代码,还有渲染线程--包括gif图的动效)都会停止下来。即使我的DOM操作语句(显示loading gif图)是在发起ajax请求的前一句,这个同步请求也会“迅速”将UI线程阻塞,不给它执行的时间。这就是代码失效的原因。
解决方法是用Deferred!同时不要将async改成false即保证ajax请求是异步的。代码大致思路如下:
function handleData(){ var defer = $.Deferred(); $.ajax({ url : "manage", //async : false, success: function(data){ defer.resolve(data) } }); return defer.promise(); } $(".delBtn").click(function(){ $(".loadingLayer").show(); $.when(handleData()).done(function(data){ $(".loadingLayer").hide(); alert(data); }); });
我的理解是 通过defer.resolve()主动告诉浏览器,这个ajax请求已经完成了,可以进行后面的操作了。
不过好像还是有点说不通,有没有理解得比较透彻的大侠给点拨一下。谢谢噜。
时间: 2024-10-20 00:27:41