因为项目的原因,我接触到了jQuery deferred 的这个神奇的工具,下面我用几个例子,与大家分享我的感悟。

我们有5个很耗时的函数 分别为fA、fB、fC、fD、fE  我们的需求是fA和fB同时执行,fA和fB都执行完了,就同时执行fC 和fD ,其中fC和fD只要有一个执行完了,就可以执行fE了。

先完成第一步,写5个函数,并加入deferred

 function fA(){
var dtd = $.Deferred();
console.log('fa Start');
setTimeout(function(){
console.log('fa End');
dtd.resolve();
}, 2000);
return dtd.promise();
}; function fB(){
var dtd = $.Deferred();
console.log('fb Start');
setTimeout(function(){
console.log('fb End');
dtd.resolve(); }, 3000);
return dtd.promise();
}; 22 /*** fC fD fE 省略 ***/

第二步, fA和fB都执行完了,然后XXX

先给出我的做法,我们需要用到$.when()这个函数  ,先看效果

     $.when(fA(), fB()).done(function(){
console.log('when fA, fB is solved');
});

打开控制台:

 fa Start
fb Start
fa End
fb End
when fA, fB is solved

有个问题: $.when()是什么

$.when() ,给出API文档的地址  http://www.css88.com/jqapi-1.9/jQuery.when/

$.when() 就是接受一个或多个deferred(延迟)对象作为参数, 返回一个deferred(延迟)对象,参数中的deferred对象的状态都变成resolve。就将返回值的状态置为resolve。简单来说,就是坚挺多个deferred回调,都成功,就调用成功的回调(dtd.done())我的理解就是一个deferred的异步‘与门’开关。

延伸一下,我们能自己实现一下$.when()吗? 按照刚刚的分析我试了一下,如下:

 $.extend({
"myWhen": function(){
var args = arguments;
var dtd = $.Deferred();
var argLen = args.length;
var solveCount = 0; var argSolve = function(){
if(solveCount >= (argLen - 1)){
dtd.resolve();
}else{
solveCount++;
}
} $.each(args, function (i_dtd, v_dtd){
v_dtd.done(argSolve);
}); return dtd.promise();
}
});

调用也改成我们自己的方法:

 $.myWhen(fA(), fB()).done(function(){
console.log('when fA, fB is solved');
});

打开控制台:

fa Start
fb Start
fa End
fb End
when fA, fB is solved

看来我们的myWhen 成功了。这个只是我们为了学习而造的轮子,下面的例子还是用$.when()

第三步,同时执行fC、fD,只要有一个成功就执行fE。

问题来了,$.when是与门开关,那么有没有或门开关呢?好像jquery还真没准备。不过我们有了上面造轮子的经验,相信应该很容易造一个$.myAtLeast()

 "myAtLeast": function(){
var args = arguments;
var dtd = $.Deferred();
var hasResolve = false;
var solve = function(){
if(!hasResolve){
dtd.resolve();
}
};
$.each(args, function (i_dtd, v_dtd){
v_dtd.done(solve);
});
return dtd.promise();
}

调用一下试试:

     $.when(fA(), fB()).done(function(){
console.log('when fA, fB has resolved');
$.myAtLeast(fC(), fD()).done(function(){
console.log('fC or fD has resolved');
fE();
});
});

打开控制台:

 fa Start
fb Start
fa End
fb End
when fA, fB has resolved
fC Start
fD Start
fC End
fC or fD has resolved
fE Start
fD End
fE End

我们可以清楚的看到,fC End后, fE就执行了,随后fD才结束。

就此,我们实现了,一开始定义的需求。

写的仓促,望大家指出文章中不对的地方。谢谢!

jQuery deferred 使用心得的更多相关文章

  1. javascript源代码学习之五——jQuery.deferred

    jQuery.Defered——异步队列用于管理一组回调函数(成功resolve,失败reject,消息progress),基于上一节实现的jQuery.callbacks完成. done,fail, ...

  2. JS魔法堂:jQuery.Deferred(jQuery1.5-2.1)源码剖析

    一.前言 jQuery.Deferred作为1.5的新特性出现在jQuery上,而jQuery.ajax函数也做了相应的调整.因此我们能如下的使用xhr请求调用,并实现事件处理函数晚绑定. var p ...

  3. 深入分析,理解jQuery.Deferred源码

    前言: 如果你对jQuery.Callback回调对象不了解,或者只掌握其方法,但是没有通过阅读源码理解,可以先阅读 前一章jQuery.Callbacks源码解读二,因为只有完全理解jQuery.C ...

  4. 通过 ES6 Promise 和 jQuery Deferred 的异同学习 Promise

    Deferred 和 Promise ES6 和 jQuery 都有 Deffered 和 Promise,但是略有不同.不过它们的作用可以简单的用两句话来描述 Deffered 触发 resolve ...

  5. jquery.Deferred promise解决异步回调

    我们先来看一下编写AJAX编码经常遇到的几个问题: 1.由于AJAX是异步的,所有依赖AJAX返回结果的代码必需写在AJAX回调函数中.这就不可避免地形成了嵌套,ajax等异步操作越多,嵌套层次就会越 ...

  6. 第三十四课:jQuery Deferred详解2

    上一课主要分析了jQuery1.51版本的jQuery Deferred.在jQuery1.6中,jQuery Deferred添加了两个方法,always,pipe. always用来添加回调,无论 ...

  7. 第三十三课:jQuery Deferred详解1

    之前我们讲了Mochikit Deferred,JSDeferred,现在讲jQuery Deferred.首先,我们先来讲下他们的区别: 在保存回调函数时,Mochikit Deferred(doj ...

  8. 使用 jQuery Deferred 和 Promise 创建响应式应用程序

    这篇文章,我们一起探索一下 JavaScript 中的 Deferred 和 Promise 的概念,它们是 JavaScript 工具包(如Dojo和MochiKit)中非常重要的一个功能,最近也首 ...

  9. 利用 Jquery Deferred 异步你的程序

    最近在做公司QA系统改造时,有这样的一个场景. QA系统中有些数据项需要从JIRA平台(一个国外项目与事务跟踪工具)中获取,JIRA平台提供了很完善的Rest API. 现在的要求是,在QA系统中提交 ...

随机推荐

  1. html-3

    <hr> 下划线实体:想在页面显示被浏览器解析的内容为表格添加标题<caption>跟tr同级,只在<table>下 <link> 为页面加小图标 在& ...

  2. Fortran和C的编译器PGI部署

    平台信息 Description: CentOS Linux release 7.6.1810 (Core) 安装步骤 获取PGCC:社区版是免费的,自带license.dat 解压下载的压缩包:ta ...

  3. hadoop的一些命令技巧

    hadoop fs -cat <hdfspath> hadoop fs -cat <hdfspath>|more #more参数可是分页显示文件内容 echo abcd | h ...

  4. Java基础11-数组

    1.使用数组步骤: (1)声明数组 int[] a; (2)分配空间 a=new int[5]; (3)赋值 a[0]=1;  int类型数组如果没有赋值,默认值为0,String类型数组默认为nul ...

  5. 案例53-crm练习修改客户功能实现

    1 CustomerAction 完整代码: package www.test.web.action; import java.io.File; import org.apache.commons.l ...

  6. Spring Boot使用mongo的GridFS模块

    1. GridFS简介 GridFS是Mongo的一个子模块,使用GridFS可以基于MongoDB来持久存储文件.并且支持分布式应用(文件分布存储和读取).作为MongoDB中二进制数据存储在数据库 ...

  7. tck/tl 以及expect脚本

    最近有用到,利用expcet脚本自动登录到远程服务器并提权执行脚本. 搜集的知识如下: tcl/tk参考——列表操作lindex expect脚本解释 代码如下 #!/usr/bin/expect - ...

  8. vue中添加echarts

    方法一:全局引入echarts 步骤: 1.全局安装 echarts依赖.        cnpm install echarts -- save 2.引入echarts模块,在Vue项目的main. ...

  9. XtraReport三动态数据绑定

    代码还用上一节的,把Report的Datasource去掉.各个绑定的字段也去掉,有了第二节的基础,现在看这个就不难了,无非就是传到report一个数据集,在把这个数据集绑定到各控件里 清空detai ...

  10. SpingCloud微服务架构学习(一)之服务提供者与服务消费者

    微服务构建的是分布式系统,各个微服务之间通过网络进行服务调用,这就有了服务提供者(被调用方)和服务消费者(调用方),以电影售票系统为例,假设服务调用关系如下图所示: 围绕此场景,我们先编写一个用户微服 ...