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 相关文章推荐
jQuery 位置插件
Dec 25 Javascript
关于html+ashx开发中几个问题的解决方法
Jul 18 Javascript
用jQuery模拟页面加载进度条的实现代码
Dec 19 Javascript
简介JavaScript中的italics()方法的使用
Jun 08 Javascript
开启Javascript中apply、call、bind的用法之旅模式
Oct 28 Javascript
jQueryUI Datepicker组件设置日期高亮
Oct 13 Javascript
AngularJS指令与控制器之间的交互功能示例
Dec 14 Javascript
前端js弹出框组件使用方法
Aug 24 Javascript
实现一个 Vue 吸顶锚点组件方法
Jul 10 Javascript
js构造函数constructor和原型prototype原理与用法实例分析
Mar 02 Javascript
js实现删除json中指定的元素
Sep 22 Javascript
JavaScript实现显示和隐藏图片
Apr 29 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
人尽可用的Windows技巧小贴士之下篇
2007/03/22 PHP
PHP XML数据解析代码
2010/05/26 PHP
php生成带logo二维码方法小结
2016/04/08 PHP
PHP加密3DES报错 Call to undefined function: mcrypt_module_open() 如何解决
2016/04/17 PHP
PHP中header函数的用法及其注意事项详解
2016/06/13 PHP
PHP中phar包的使用教程
2017/06/14 PHP
PHP面向对象程序设计之构造方法和析构方法详解
2019/06/13 PHP
通过JS 获取Mouse Position(鼠标坐标)的代码
2009/09/21 Javascript
学习ExtJS border布局
2009/10/08 Javascript
js 字符串转化成数字的代码
2011/06/29 Javascript
js调用webservice构造SOAP进行身份验证
2016/04/27 Javascript
Vue.js每天必学之计算属性computed与$watch
2016/09/05 Javascript
详解堆的javascript实现方法
2016/11/29 Javascript
JS小数转换为整数的方法分析
2017/01/07 Javascript
老生常谈js中0到底是 true 还是 false
2017/03/08 Javascript
vue指令之表单控件绑定v-model v-model与v-bind结合使用
2019/04/17 Javascript
在vue中实现禁止屏幕滚动,禁止屏幕滑动
2020/07/22 Javascript
vue 通过绑定事件获取当前行的id操作
2020/07/27 Javascript
JS绘图Flot如何实现动态可刷新曲线图
2020/10/16 Javascript
python数据结构之线性表的顺序存储结构
2018/09/28 Python
Python 实现某个功能每隔一段时间被执行一次的功能方法
2018/10/14 Python
运用PyTorch动手搭建一个共享单车预测器
2019/08/06 Python
django执行原始查询sql,并返回Dict字典例子
2020/04/01 Python
Python简单实现词云图代码及步骤解析
2020/06/04 Python
Python操作MySQL数据库的示例代码
2020/07/13 Python
深入了解canvas在移动端绘制模糊的问题解决
2019/04/30 HTML / CSS
Calzedonia美国官网:意大利风格袜子、打底裤和沙滩装
2018/07/19 全球购物
Java基础类库面试题
2013/09/04 面试题
初中数学教学反思
2014/01/16 职场文书
给实习单位的感谢信
2014/02/01 职场文书
给全校老师的建议书
2014/03/13 职场文书
活动总结模板
2014/05/09 职场文书
道歉情书大全
2015/05/12 职场文书
《我是什么》教学反思
2016/02/16 职场文书
Python-OpenCV教程之图像的位运算详解
2021/06/21 Python
Java中API的使用方法详情
2022/04/06 Java/Android