jquery 之 Deferred 使用
Deferred是jquery的promise接口的实现。他是非同步操作的通用接口,可以看作是完成一个任务之后再执行另外一个任务。
观察者模式是开发中经常使用的模式,这个模式由两个主要部分组成:主题和观察者。通过观察者模式,实现主题和观察者的解耦.
主题负责发布内容,而观察者则接收主题发布的内容。
在 jQuery 中,实现观察者模式的就是 Deferred 了,我们先看它的使用。
使用 Deferred
// 定义主题
var subject = (function(){
var dfd = $.Deferred(); var task = function()
{
// 发布内容
dfd.resolve("Alice");
} setTimeout( task, 3000); return dfd.promise();
})(); // 两个观察者
var fn1 = function(content){
console.log("fn1: " + content );
} var fn2 = function(content){
console.log("fn2: " + content );
} // 注册观察者
$.when( subject )
.done( fn1 )
.done( fn2 );
在 jQuery 中,甚至可以提供两个主题同时被观察, 需要注意的是,要等两个主题都触发之后,才会真正触发,每个观察者一次得到这两个主题,所以参数变成了 2 个。
// 定义主题
var subjectAlice = (function(){
var dfd = $.Deferred(); var task = function()
{
// 发布内容
dfd.resolve("Alice");
} setTimeout( task, 3000); return dfd.promise();
})(); var subjectTom = (function(){
var dfd = $.Deferred(); var task = function()
{
// 发布内容
dfd.resolve("Tom");
} setTimeout( task, 1000); return dfd.promise();
})(); // 两个观察者
var fn1 = function(content1, content2){
console.log("fn1: " + content1 );
console.log("fn1: " + content2 );
} var fn2 = function(content1, content2){
console.log("fn2: " + content1 );
console.log("fn2: " + content2 );
} // 注册观察者
$.when( subjectAlice, subjectTom )
.done( fn1 )
.done( fn2 );
$.when()方法
$.when()接受多个deferred对象作为参数,当它们全部运行成功后,才调用resolved状态的回调函数,但只要其中有一个失败,就调用rejected状态的回调函数。它相当于将多个非同步操作,合并成一个。
例如:
$.when(
$.ajax( "/main.php" ),
$.ajax( "/modules.php" ),
$.ajax( "/lists.php" )
).then(successFunc, failureFunc);
上面代码表示,要等到三个ajax操作都结束以后,才执行then方法指定的回调函数。
when方法里面要执行多少个操作,回调函数就有多少个参数,对应前面每一个操作的返回结果。
例如:
$.when(
$.ajax( "/main.php" ),
$.ajax( "/modules.php" ),
$.ajax( "/lists.php" )
).then(function (resp1, resp2, resp3){
console.log(resp1);
console.log(resp2);
console.log(resp3);
});
上面代码的回调函数有三个参数,resp1、resp2和resp3,依次对应前面三个ajax操作的返回结果。
then()方法
then()的作用也是指定回调函数,它可以接受三个参数,也就是三个回调函数。第一个参数是resolve时调用的回调函数,第二个参数是reject时调用的回调函数,第三个参数是progress()方法调用的回调函数。
deferred.then( doneFilter [, failFilter ] [, progressFilter ] )
then()和done()的区别
在jQuery 1.8之后,then()返回一个新的deferred对象,而done()返回的是原有的deferred对象。
如果then()指定的回调函数有返回值,该返回值会作为参数,传入后面的回调函数。
例如:如下代码:
var defer = jQuery.Deferred();
defer.done(function(a,b){
return a * b;
}).done(function( result ) {
console.log("result = " + result);
}).then(function( a, b ) {
return a * b;
}).done(function( result ) {
console.log("result = " + result);
}).then(function( a, b ) {
return a * b;
}).done(function( result ) {
console.log("result = " + result);
});
defer.resolve( 2, 3 );
返回的结果为:
result = 2
result = 6
result = NaN
分析:
1)上面的第一个result是第一个result的最后一个done()的输出,前一个done的return不会传递到这里,所以result是resolve的第一个参数
2)第二个result是第二个deferred的输出,第一个then所带的function的输入,传入第二个deferred,因此第五个done能够接受到2*3的result。
3)第三个result是第三个deferred的输出,第二个then执行时,只有a,没有b(上一个then执行时返回的是a*b,所以再第三个then执行时只有a,没有b),所以result是NaN。 综合例子如下:
var requestInfo = function() {
var defered = $.Deferred();
var url = "https://api.ffan.com/activity/v1/homepage/index";
$.ajax(url, {
dataType: "jsonp",
jsonp: "callback",
timeout: 5000,
data: {
type: "cityList"
}
}).then(function(response) {
if (response && response.data && response.data[0]) {
defered.resolve(response.data[0].cityList);
}
})
return defered.promise();
}
var cityInfo = function(result) {
var list = _.groupBy(result, function(city) {
return city.cityPinYin.charAt(0).toUpperCase();
});
_.each(list,function(city,key){
console.log(key);
_.each(city,function(item,index){
console.log("item.cityId="+item.cityId);
console.log("item.cityName="+item.cityName);
})
})
//获取第一条数据的cityId
var cityId=list["A"][0].cityId;
//返回值,供下一个then调用
return {
id:cityId
}
}
var info=function(result){
var id=result.id;//上一个then返回的值
console.log("cityid="+id);
return true;
}
调用:
$.when(requestInfo())
.then(cityInfo)
.then(info);
jquery 之 Deferred 使用的更多相关文章
- jQuery之Deferred源码剖析
一.前言 大约在夏季,我们谈过ES6的Promise(详见here),其实在ES6前jQuery早就有了Promise,也就是我们所知道的Deferred对象,宗旨当然也和ES6的Promise一样, ...
- jQuery的deferred对象详解
jQuery的deferred对象详解请猛击下面的链接 http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_ ...
- jQuery的deferred对象学习
#copy { background-color: lightgreen; padding: 15px; margin: 10px } 一.deferred对象简介 deferred对象是jquery ...
- jquery 之 Deferred 使用与实现
观察者模式是开发中经常使用的模式,这个模式由两个主要部分组成:主题和观察者.通过观察者模式,实现主题和观察者的解耦. 主题负责发布内容,而观察者则接收主题发布的内容.通常情况下,观察者都是多个,所以, ...
- jQuery的deferred对象详解(转载)
本文转载自: jQuery的deferred对象详解(转载)
- jQuery的Deferred
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- jQuery的deferred对象
应用场景:处理异步任务 看到一篇阮一峰老师的博客挺好的讲的就是jQuery的deferred对象.坦诚讲之前没有怎么用过这个东东呢. 摘其中几点记录下 (1) $.Deferred() 生成一个def ...
- jQuery的deferred对象详解(一)
最近一段时间,都在研究jquery里面的$.Deffered对象,几天都搞不明白,其中源码的运行机制,网上查找了相关的资料,<jQuery的deferred对象详解>阮一峰老师的文章,里面 ...
- jQuery的deferred对象解析
参考: jQuery的deferred对象详解:http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_defe ...
- [转] jQuery的deferred对象详解
jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本. 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5.0版本开始引入的一个新功能----deferred对象. ...
随机推荐
- PHP 获得域控内用户的计算机登录名
一个需求: 在域控范围获得访问用户的计算机名.方法: 1.测试软件环境: XAMPP Control Panel V3.2.1 , Apache version 2.4.7 2.Apache 2.2 ...
- Server Objects Extension(SOE)开发(三)
前言 SOE出现之前,一些复杂.耗时的gis操作,通常都是使用gp服务实现的.前面将gp服务和soe进行了对比分析,为了测试两种的效率,曾经做了个demo,使用soe和gp同时执行相同的业务逻辑,记录 ...
- 利用jdk中工具完成Java程序监控方法记录
转载加自己整理的部分内容,转载自:http://jiajun.iteye.com/blog/810150 记录下JConsole使用方法 一.JConsole是什么 从Java 5开始 引入了 ...
- 请听一个故事------>你真的认为iPhone只是一部手机?苹果惊天秘密!!
在网上看到的一篇小说,感觉有点意思,转载过来大家一起围观下,作者很幽默很风趣. 导读:iPhone的隐藏功能!Jobs的军方身份!图灵服毒自杀的传奇故事!中兴华为的神秘背景! 你真的认为iPhone只 ...
- STL学习笔记— —容器map和multimap
简单介绍 在头文件<map> 中定义 namespace std { template <typename Key, typename T, typename Compare = l ...
- 2. 安装 Kerberos
2.1. 环境配置 安装kerberos前,要确保主机名可以被解析. 主机名 内网IP 角色 Vmw201 172.16.18.201 Master KDC Vmw202 172.16.18.202 ...
- JavaScript四则运算计算器
直接上代码: 首先是HTML代码 <form> 第一个数字:<br> <input type="text" id="num1"&g ...
- python常用模块——os模块
python编程时,经常和文件.目录打交道,这就离不开os模块,os模块包含普遍的操作系统功能,与具体的平台无关,列举一些常用的命令. 1.os.name:字符串指示你正在使用的平台.windows是 ...
- Python基础(10)_内置函数、匿名函数、递归
一.内置函数 1.数学运算类 abs:求数值的绝对值 divmod:返回两个数值的商和余数,可用于计算页面数 >>> divmod(5,2) (2, 1) max:返回可迭代对象中的 ...
- Loadrunder之脚本篇——参数化在场景中的运用
Action() { lr_eval_string("{NewParam}"); lr_eval_string("{NewParam}"); return 0; ...