jQuery中借助deferred来请求及判断AJAX加载的实例讲解
ajax请求异步队列加载
我们在开发程序的时候通常会碰到使用ajax加载数据显示到列表的情况。ajax默认使用异步加载(async:true)。为什么不使用同步呢,因为ajax同步加载会UI渲染线程阻塞的问题。通常表现为在加载大量数据时由于加载时间过长导致页面不能点击、gif动画卡死以及浏览器崩溃等问题。所以,一般情况下,尽量使用ajax异步加载。
可是,我们有些时候的需求要求ajax同步加载,一个加载完再加载下一个,即所谓的队列。前面我们有说过,同步加载会引起UI渲染阻塞问题。那么我们要怎么实现顺序加载而不引起该问题呢?
示例代码一:
<scriptsrc="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script>
$(function(){
$("#clickBtn").on("click",function(){
getData(0,10);//输出0-9
})
})
functiongetData(i,length){
$.ajax({
type:"post",
url:"setDeffer.php",
data:{
data:i
},
async:true,//异步
success:function(data){
$("#showArea").text($("#showArea").text()+data+"\n");
if(i<length-1){
getData(i+1,length);
}
}
});
}
</script>
PHP后台代码:
<?php $str=$_POST["data"]; sleep(1);//延迟1秒 echo"输出".$str; ?>
当然,jquery也提供了我们deferred对象来解决回调函数的问题。
示例代码二:
<scriptsrc="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script>
$(function(){
$("#clickBtn").on("click",function(){
recycleData(0,10);//输出0-9
})
})
functiongetData(i){
vardefer=$.Deferred();
$.ajax({
type:"post",
url:"setDeffer.php",
data:{
data:i
},
async:true,//异步
success:function(data){
$("#showArea").text($("#showArea").text()+data+"\n");
defer.resolve(data);
}
});
returndefer.promise();
}
functionrecycleData(i,length){
$.when(getData(i)).done(function(data){//这里的data为defer在ajax保存下来的数据
if(i<length-1){
recycleData(i+1,length);//递归
}
})
}
</script>
这里首先创建一个deffered对象,在ajax的success函数中将ajax返回的数据保存在deffered对象中,然后返回deffered对象。这样就保证了在下一次ajax请求的时候这个ajax已经请求完成。deferred对象的好处包括它允许你给一个事件自由添加多个回调函数。或者给多个事件统一指定回调函数。
用jquery的deferred对象实现判断页面中所有图片加载完成
如果我们加载的是图片,对于图片是否加载完成,我们平时可以用监听图片load方法来进行。今天主要介绍用jquery的deferred对象来进行判断。
关于jquery的deferred对象,是jquery的重点和难点。对于执行较长时间的函数,我们通常用deferred对象。
关于deferred对象,我在这里稍微介绍一下$.when().then()
functionsuccessFunc(){console.log(“success!”);}
functionfailureFunc(){console.log(“failure!”);}
$.when(
$.ajax("/main.php"),
$.ajax("/modules.php"),
$.ajax(“/lists.php”)
).then(successFunc,failureFunc);
可以同时调用多个ajax,然后通过then来返回成功或者失败。
或者
$.when($.ajax("test1.html"),$.ajax("test2.html"))
.done(function(){alert("哈哈,成功了!");})
.fail(function(){alert("出错啦!");});
我们回到正题来,用jquery的deferred对象实现判断页面中所有图片加载完成
vardefereds=[];//定义一个数组存放Deferred对象
$imgs.each(function(){//imgs循环所有图片
vardfd=$.Deferred();//新建一个deferred对象
$(this).load(dfd.resolve());//图片加载完成之后,改变deferred对象的执行状态
defereds.push(dfd);//push到数组中
});
$.when.apply(null,defereds).done(function(){
console.log('loadcompeleted');
});
因为$.when支持的参数是$.when(dfd1,dfd2,dfd3,...),所以我们这里使用了apply来接受数组参数。
上面提到了apply(),又引申到了在JS中,call()方法和apply()方法
我在这里稍微介绍一下apply()
假如我们有prints函数:
functionprints(a,b,c,d){
console.log(a+b+c+d);
}
functionexample(a,b,c,d){
prints.apply(this,[a,b,c,d]);
}
example("1","sd","wq","wqe")//输出:1sdwqwqe
或者我们可以这么写:
prints.apply(null,["脚","本","之","家"]);//输出:毛票票