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 使用的更多相关文章

  1. jQuery之Deferred源码剖析

    一.前言 大约在夏季,我们谈过ES6的Promise(详见here),其实在ES6前jQuery早就有了Promise,也就是我们所知道的Deferred对象,宗旨当然也和ES6的Promise一样, ...

  2. jQuery的deferred对象详解

    jQuery的deferred对象详解请猛击下面的链接 http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_ ...

  3. jQuery的deferred对象学习

    #copy { background-color: lightgreen; padding: 15px; margin: 10px } 一.deferred对象简介 deferred对象是jquery ...

  4. jquery 之 Deferred 使用与实现

    观察者模式是开发中经常使用的模式,这个模式由两个主要部分组成:主题和观察者.通过观察者模式,实现主题和观察者的解耦. 主题负责发布内容,而观察者则接收主题发布的内容.通常情况下,观察者都是多个,所以, ...

  5. jQuery的deferred对象详解(转载)

    本文转载自: jQuery的deferred对象详解(转载)

  6. jQuery的Deferred

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  7. jQuery的deferred对象

    应用场景:处理异步任务 看到一篇阮一峰老师的博客挺好的讲的就是jQuery的deferred对象.坦诚讲之前没有怎么用过这个东东呢. 摘其中几点记录下 (1) $.Deferred() 生成一个def ...

  8. jQuery的deferred对象详解(一)

    最近一段时间,都在研究jquery里面的$.Deffered对象,几天都搞不明白,其中源码的运行机制,网上查找了相关的资料,<jQuery的deferred对象详解>阮一峰老师的文章,里面 ...

  9. jQuery的deferred对象解析

    参考: jQuery的deferred对象详解:http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_defe ...

  10. [转] jQuery的deferred对象详解

    jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本. 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5.0版本开始引入的一个新功能----deferred对象. ...

随机推荐

  1. js特殊字符过滤

    //匹配中文 数字 字母 下划线 var checkInput = function (str) { var pattern =var pattern = /^[\w\u4e00-\u9fa5]+$/ ...

  2. 剖析与优化 Go 的 web 应用

    https://mp.weixin.qq.com/s/HDsbZLOK3h8-XjejvPH2sA https://studygolang.com/articles/12685

  3. git github usage

    以gerrit-trigger-plugin为例,下面的链接都是从相应页面上直接拷贝的. 法一:不用github的账号,打开这个库在github上的主页,运行下面命令即可 read only 运行命令 ...

  4. python cookbook第三版学习笔记二十:可自定义属性的装饰器

    在开始本节之前,首先介绍下偏函数partial.首先借助help来看下partial的定义 首先来说下第一行解释的意思: partial 一共有三个部分: (1)第一部分也就是第一个参数,是一个函数, ...

  5. Hadoop权威指南读书笔记

    本书中提到的Hadoop项目简述 Common:一组分布式文件系统和通用I/O的组件与接口(序列化.javaRPC和持久化数据结构). Avro:一种支持高效.跨语言的RPC以及永久存储数据的序列化系 ...

  6. 4.2 使用STM32控制MC20发送短信

    需要准备的硬件 MC20开发板 1个 https://item.taobao.com/item.htm?id=562661881042 GSM/GPRS天线 1根 https://item.taoba ...

  7. 爬虫四 selenium模块

    一.介绍 selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题 selenium本质是通过驱动浏览器,完全模拟浏览器的操作, ...

  8. 标准c字符和字符串的使用方法

    cppreference.com -> Standard C String & Character -> 详解 标准c字符和字符串 atof 语法:     #include &l ...

  9. 通过ip得到所在城市,以及城市所在经纬度坐标(监控系统中用的该代码,小航哥)

    监控系统中就是利用的该段代码,实现通过ip得到所在城市,以及城市所在经纬度坐标,最后得以利用echarts实现模拟迁移的效果 api官方介绍: http://lbsyun.baidu.com/inde ...

  10. I.mx6s上移植wm8960驱动(基于linux3.0.101版本)

    I.mx6s上移植wm8960驱动   此篇博文只记录移植的步骤,其他不做分析.首先上一张wm8960的硬件连接图: 1  上电操作   配置wm8960的上电脚,文件位置:arch/arm/mach ...