jQuery中借助deferred来请求及判断AJAX加载的实例讲解


Posted in Javascript onMay 24, 2016

ajax请求异步队列加载
我们在开发程序的时候通常会碰到使用ajax加载数据显示到列表的情况。ajax默认使用异步加载(async:true)。为什么不使用同步呢,因为ajax同步加载会UI渲染线程阻塞的问题。通常表现为在加载大量数据时由于加载时间过长导致页面不能点击、gif动画卡死以及浏览器崩溃等问题。所以,一般情况下,尽量使用ajax异步加载。
可是,我们有些时候的需求要求ajax同步加载,一个加载完再加载下一个,即所谓的队列。前面我们有说过,同步加载会引起UI渲染阻塞问题。那么我们要怎么实现顺序加载而不引起该问题呢?
示例代码一:

<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script>
$(function(){
 $("#clickBtn").on("click",function(){
  getData(0,10);//输出0-9
 })
})

function getData(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对象来解决回调函数的问题。
示例代码二:

<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script>
$(function(){
 $("#clickBtn").on("click",function(){
  recycleData(0,10);//输出0-9
 })
})

function getData(i){
 var defer = $.Deferred();
 $.ajax({
  type:"post",
  url:"setDeffer.php",
  data:{
   data:i
  },
  async:true,//异步
  success:function(data){
   $("#showArea").text($("#showArea").text()+data+"\n");
   defer.resolve(data);
  }
 });
 return defer.promise();
}
function recycleData(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()

function successFunc(){ console.log( “success!” ); } 
function failureFunc(){ 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对象实现判断页面中所有图片加载完成

var defereds = []; //定义一个数组存放Deferred对象

$imgs.each(function() { //imgs循环所有图片
  var dfd = $.Deferred();// 新建一个deferred对象

  $(this).load(dfd.resolve());// 图片加载完成之后,改变deferred对象的执行状态
  defereds.push(dfd);//push到数组中
});
$.when.apply(null, defereds).done(function() {
  console.log('load compeleted');
});

因为 $.when 支持的参数是 $.when(dfd1, dfd2, dfd3, ...),所以我们这里使用了 apply 来接受数组参数。

上面提到了apply(),又引申到了 在JS中,call()方法和apply()方法

我在这里稍微介绍一下apply()

假如我们有prints函数:

function prints(a,b,c,d){
    console.log(a+b+c+d);
  }
  function example(a,b,c,d){
    prints.apply(this,[a,b,c,d]);
  }
  example("1","sd","wq","wqe") //输出:1sdwqwqe

或者我们可以这么写:

prints.apply(null,["脚","本","之","家"]);//输出:三水点靠木
Javascript 相关文章推荐
javascript 函数式编程
Aug 16 Javascript
javascript得到XML某节点的子节点个数的脚本
Oct 11 Javascript
浅析Prototype的模板类 Template
Dec 07 Javascript
实现局部遮罩与关闭原理及代码
Feb 04 Javascript
JavaScript限定复选框的选择个数示例代码
Aug 25 Javascript
根据当前时间在jsp页面上显示上午或下午
Aug 18 Javascript
详解js中构造流程图的核心技术JsPlumb(2)
Dec 08 Javascript
jQuery实现鼠标跟随效果
Feb 20 Javascript
vue实现todolist单页面应用
Apr 11 Javascript
node Buffer缓存区常见操作示例
May 04 Javascript
解决layui弹框失效的问题
Sep 09 Javascript
vue 内联样式style中的background用法说明
Aug 05 Javascript
JS 清除字符串数组中,重复元素的实现方法
May 24 #Javascript
原生js的数组除重复简单实例
May 24 #Javascript
实例讲解jQuery中对事件的命名空间的运用
May 24 #Javascript
json传值以及ajax接收详解
May 24 #Javascript
JS获取屏幕高度的简单实现代码
May 24 #Javascript
基于JavaScript实现回到页面顶部动画代码
May 24 #Javascript
jquery简单插件制作(fn.extend)完整实例
May 24 #Javascript
You might like
PHP 基本语法格式
2009/12/15 PHP
PHP互换两个变量值的方法(不用第三变量)
2016/11/14 PHP
PHP表单验证内容是否为空的实现代码
2016/11/14 PHP
ThinkPHP实现登录退出功能
2017/06/29 PHP
静态的动态续篇之来点XML
2006/08/15 Javascript
javascript Object与Function使用
2010/01/11 Javascript
javascript图片切换综合实例(循环切换、顺序切换)
2016/01/13 Javascript
jQuery点击输入框显示验证码图片
2016/05/19 Javascript
AngularJs基于角色的前端访问控制的实现
2016/11/07 Javascript
js输入框使用正则表达式校验输入内容的实例
2017/02/12 Javascript
angular中实现li或者某个元素点击变色的两种方法
2017/07/27 Javascript
详解ES6 Promise对象then方法链式调用
2018/10/20 Javascript
利用JS响应式修改vue实现页面的input值
2019/09/02 Javascript
js实现点击选项置顶动画效果
2020/08/25 Javascript
小程序实现列表倒计时功能
2021/01/29 Javascript
[01:03:59]2018DOTA2亚洲邀请赛3月30日 小组赛B组VGJ.T VS Secret
2018/03/31 DOTA
Centos Python2 升级到Python3的简单实现
2016/06/21 Python
python环形单链表的约瑟夫问题详解
2018/09/27 Python
python将.ppm格式图片转换成.jpg格式文件的方法
2018/10/27 Python
浅谈Python_Openpyxl使用(最全总结)
2019/09/05 Python
基于TensorFlow的CNN实现Mnist手写数字识别
2020/06/17 Python
详解pyinstaller生成exe的闪退问题解决方案
2020/06/19 Python
django form和field具体方法和属性说明
2020/07/09 Python
python Matplotlib数据可视化(1):简单入门
2020/09/30 Python
Python获取指定网段正在使用的IP
2020/12/14 Python
Levi’s西班牙官方网站:李维斯,著名的牛仔裤品牌
2020/08/20 全球购物
工商治理实习生的自我评价
2014/01/15 职场文书
2014年德育工作总结
2014/11/20 职场文书
安全保证书
2015/01/16 职场文书
统计员岗位职责范本
2015/04/14 职场文书
机关保密工作承诺书
2015/05/04 职场文书
甲午大海战观后感
2015/06/02 职场文书
同学会感言
2015/07/30 职场文书
2015大一新生军训感言
2015/08/01 职场文书
中职班主任培训心得体会
2016/01/07 职场文书
MySQL创建管理KEY分区
2022/04/13 MySQL