相关文章推荐
腼腆的松球  ·  python ...·  2 周前    · 
不要命的芒果  ·  android ...·  6 天前    · 
飞翔的枕头  ·  Jquery ajax ...·  3 天前    · 
欢乐的佛珠  ·  C# ...·  10 月前    · 
痴情的铁板烧  ·  python ...·  1 年前    · 
刚分手的鼠标  ·  gdb not in executable ...·  1 年前    · 

ajax 执行http网络请示时时,让遮罩层显示,ajax加载完毕后遮罩层消失。

因为我想让loadChart()在赋值操作后执行,但如果async设为 true 时,往往会先执行loadChart(),之后才会赋值,

所以我只能将ajax设为同步。但同步后无论我怎么点按钮,遮罩层都不会出来。

解决方法 1:

这时:只有:async:true , loading mask层才会出来

原因就是ajax的async设置为true时,ajax会委托浏览器另起一个线程,此线程与js线程和ui线程不冲突,只是在执行完成后再插入js事件环。

而ajax的async设置为false时并没有启动单独的线程,还是在js主线程中执行,所以会与浏览器的渲染(UI)线程和js线程是互斥的,在执行js耗时操作时, 页面渲染 会被阻塞掉。

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

解决方法 2:

那么需要使用到: deferred对象。

总之,想让ajax走完再加载页面,就要使用同步。但是只要同步,ajax就会阻塞ui线程,使得loading显示不出来。

只有使用了deffer对象和$.when(),既可以ajax设为异步,保证了loading的正常显示,又可以保证在ajax走完再加载页面。因为$.when().done()会在deffer.resolve()之前的代码全部走完后才走done中的代码。

我改成这样。由于ajax为同步时点击切换比较卡。能用异步最好还是用异步,用defferred对象后就可以把async换成true了。$.when()函数只接受defferred对象,所以我们在toGetData中需要先创建对象,再return就解决了。defer.resolve(ret)用于控制ajax何时结束,比如我执行完赋值操作结束ajax,进入.done()中的回调函数,它还可以把数据ret也带出来使用,这里我没有用到,这里执行完loadChart()操作后遮罩层消失。所以它能保证deffer.resolve之前的代码执行完再执行回到函数,async设为true也没任何影响。

这样就完美解决了因为ajax阻塞线程导致loading层出不来的问题啦。

<script>
var data;
function toGetData() {
var defer = $.Deferred();
$.ajax({
url: 'xxx',
type: "post", // 请求类型
data: {
},
dataType: 'json',
async: true, // 是否异步
success: function (ret) {
if (ret) {
data=ret;
defer.resolve(ret)

} else {
alert("无数据");
}
}
});
return defer;
}
$('button').click(function(){
$(".shadow").show()
$.when(toGetData()).done(function(ret){
loadChart()
$(".shodow").hide()   //所有的ajax的逻辑可以在这个地方进行处理
});
})
</script>

什么是deferred对象?

开发网站的过程中,我们经常遇到某些耗时很长的javascript操作。其中,既有异步的操作(比如ajax读取服务器数据),也有同步的操作(比如遍历一个大型数组),它们都不是立即能得到结果的。

通常的做法是,为它们指定回调函数(callback)。即事先规定,一旦它们运行结束,应该调用哪些函数。

但是,在回调函数方面,jQuery的功能非常弱。为了改变这一点,jQuery开发团队就设计了 deferred对象

简单说,deferred对象就是jQuery的回调函数解决方案。 在英语中,defer的意思是"延迟",所以deferred对象的含义就是"延迟"到未来某个点再执行。

它解决了如何处理耗时操作的问题,对那些操作提供了更好的控制,以及统一的编程接口。它的主要功能,可以归结为四点。下面我们通过示例代码,一步步来学习。

$.ajax({

url: "test.html",

success: function(){
alert("哈哈,成功了!");
},

error:function(){
alert("出错啦!");
}

ajax操作的链式写法

$.ajax("test.html")

.done(function(){ alert("哈哈,成功了!"); })

.fail(function(){ alert("出错啦!"); });

指定同一操作的多个回调函数

$.ajax("test.html")

.done(function(){ alert("哈哈,成功了!");} )

.fail(function(){ alert("出错啦!"); } )

.done(function(){ alert("第二个回调函数!");} );

多个操作指定回调函数

$.when($.ajax("test1.html"), $.ajax("test2.html"))

.done(function(){ alert("哈哈,成功了!"); })

.fail(function(){ alert("出错啦!"); });

普通操作的回调函数接口

var wait = function(){

var tasks = function(){

alert("执行完毕!");

setTimeout(tasks,5000);

普通回调函数需要改造:

var dtd = $.Deferred(); // 新建一个deferred对象

var wait = function(dtd){

var tasks = function(){

alert("执行完毕!");

dtd.resolve(); // 改变deferred对象的执行状态

setTimeout(tasks,5000);

return dtd;

$.when( wait ())

.done(function(){ alert("哈哈,成功了!"); })

.fail(function(){ alert("出错啦!"); });

上面这种写法,还是有问题。那就是dtd是一个全局对象,所以它的执行状态可以从外部改变。

jQuery的deferred对象详解 - 阮一峰的网络日志

前阵子做项目,遇到一个很奇怪的问题。 我的html 页面 执行一个删除item的操作,需要跟后台用 ajax 交互。由于后台处理的过程有点长,为了给用户更好的体验,我试图在 ajax 请求 发出前,让 页面 显示 一个 loading 的gif图,当收到后台 ajax 处理结束的信号后,再将这个 loading 图隐藏。 然而,奇怪的事情发生了。 页面 确实出现了那个gif图,但是却完全不动, 页面 出现假死的状态。 form.on('submit(add)', function(data){ data.field.companyType=$("#sltCompanyType").val(); data.field.hrCompanyTradeId=$("#sltTradeType").val();