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 相关文章推荐
Jvascript学习实践案例(开发常用)
Jun 25 Javascript
jquery交替变换颜色的三种方法 实例代码
Nov 19 Javascript
自己动手手写jQuery插件总结
Jan 20 Javascript
JS利用cookie记忆当前位置的防刷新导航效果
Oct 15 Javascript
JS设置下拉列表框当前所选值的方法
Dec 22 Javascript
JavaScript 不支持 indexof 该如何解决
Mar 30 Javascript
JQuery validate插件验证用户注册信息
May 11 Javascript
详解express与koa中间件模式对比
Aug 07 Javascript
Vue的elementUI实现自定义主题方法
Feb 23 Javascript
vue父子组件间引用之$parent、$children
May 20 Javascript
echarts浮动显示单位的实现方法示例
Dec 04 Javascript
javaScript Array api梳理
Mar 31 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 杂谈《重构-改善既有代码的设计》之五 简化函数调用
2012/05/07 PHP
优化PHP代码技巧的小结
2013/06/02 PHP
php使用Jpgraph绘制复杂X-Y坐标图的方法
2015/06/10 PHP
Ajax PHP JavaScript MySQL实现简易无刷新在线聊天室
2016/08/17 PHP
Yii2使用$this-&gt;context获取当前的Module、Controller(控制器)、Action等
2017/03/29 PHP
jQuery AJAX实现调用页面后台方法和web服务定义的方法分享
2012/03/01 Javascript
Jquery submit()无法提交问题
2013/04/21 Javascript
对比分析json及XML
2014/11/28 Javascript
jQuery实现简单滚动动画效果
2016/04/07 Javascript
详解nodejs 文本操作模块-fs模块(二)
2016/12/22 NodeJs
微信小程序 解决请求服务器手机预览请求不到数据的方法
2017/01/04 Javascript
JavaScript运动框架 多值运动(四)
2017/05/18 Javascript
React学习之事件绑定的几种方法对比
2017/09/24 Javascript
Javascript 对象(object)合并操作实例分析
2019/07/30 Javascript
VUE实现密码验证与提示功能
2019/10/18 Javascript
微信小程序定义和调用全局变量globalData的实现
2019/11/01 Javascript
vue如何实现动态加载脚本
2020/02/05 Javascript
JS如何判断对象是否包含某个属性
2020/08/29 Javascript
聊聊vue 中的v-on参数问题
2021/01/29 Vue.js
[04:26]2014DOTA2西雅图国际邀请赛 总决赛TOPPLAY
2014/07/22 DOTA
使用Python3编写抓取网页和只抓网页图片的脚本
2015/08/20 Python
Python获取命令实时输出-原样彩色输出并返回输出结果的示例
2019/07/11 Python
django foreignkey外键使用的例子 相当于left join
2019/08/06 Python
Python装饰器使用你可能不知道的几种姿势
2019/10/25 Python
Tensorflow 自定义loss的情况下初始化部分变量方式
2020/01/06 Python
python GUI库图形界面开发之PyQt5信号与槽机制、自定义信号基础介绍
2020/02/25 Python
Python基于正则表达式实现计算器功能
2020/07/13 Python
印度尼西亚综合购物网站:Lazada印尼
2016/09/07 全球购物
函授教育个人学习的自我评价
2013/12/31 职场文书
留学自荐信写作方法
2014/01/27 职场文书
《巨人的花园》教学反思
2014/02/12 职场文书
2016同学毕业寄语大全
2015/12/04 职场文书
2016大一新生军训心得体会
2016/01/11 职场文书
Mysql 性能监控及调优
2021/04/06 MySQL
pytorch中F.avg_pool1d()和F.avg_pool2d()的使用操作
2021/05/22 Python
如何利用opencv判断两张图片是否相同详解
2021/07/07 Python