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

always用来添加回调,无论成功还是失败,都会执行。

pipe就是管道的意思,对回调使用瀑布模型,上一个回调的返回值供下一个会调使用。

我们举个例子来说明下pipe与then的区别:

var deferred = $.Deferred();  //返回的是Deferred对象

var promise = deferred.pipe(function(a){return a*2}).pipe(function(a){return a*4;})   //pipe方法的返回值是Promise对象,因此promise与deferred不相等。

deferred.resolve(5);     //执行这个函数后,就会调用pipe添加进来的回调函数。第一个回调函数中的a=5,然后返回10给第二个回调函数,因此第二个回调中的a=10。

$.Deferred().then(function(a){return a*2;}).then(function(a){return a*4;}).resolve(5);

第一个回调函数中的a=5,第二个回调函数中的a=10,跟pipe方法一样。它们的区别是then方法返回的是Deferred对象,因而可以进行链式操作,而pipe方法返回的是Promise对象,不能进行链式操作。

在这个版本的jQuery中,Deferred开始在jQuery内部大规模应用了,包括queue模块,Ajax模块。

举个很好的例子:

var stuff1 = function(deferred){

  setTimeout(function(){deferred.resolve()},1000);

};

var stuff2 = function(deferred){

  setTimeout(function(){deferred.resolve()},500);

};

var stuff3 = function(deferred){

  setTimeout(function(){deferred.resolve()},800);

};

var stuff4 = function(deferred){

  setTimeout(function(){deferred.resolve()},800);

};

$.when(    //此方法接受了三个Deferred对象,只有等这三个Deferred对象的状态结束后(也就是执行了各自的resolve方法后),才会执行then添加的回调方法。

  $.Deferred(stuff1),   //此方法会执行stuff1方法,并且把新创建的Deferred对象传进去,返回此Deferred对象,1秒后,调用此Deferred对象的resolve方法。

  $.Deferred(stuff2),   //同上,只是异步处理的时间不一样。

  $.Deferred(stuff3)    //同上,这里的setTimeout的异步处理,我们可以当做是ajax请求的时间长度。

).then(stuff4);   //给$.when()方法返回的Deferred对象添加回调函数stuff4。等when方法中传入的所有Deferred对象的状态结束后,就会执行此回调stuff4.

这段代码的理解你可以当做是:有三个ajax请求,请求的地址不一样,我们需要等这三个ajax请求都返回后,把这三个请求回来的数据进行整合处理,才能进行最后一个ajax请求。

jQuery1.7添加了Callbacks模块,具体可以看:http://www.cnblogs.com/chaojidan/p/4165818.html。

而且也改写了Deferred模块。这个时候的Deferred,它是一个三链结构(doneList,failList,progressList)。progressList链添加了三个API,progress,notify,notifyWith,用来给此链添加回调和触发回调。progressList链是用来干嘛的?我们知道成功队列doneList与失败队列failList都是一次性的,也就是说触发了一次就不能再触发了。但是有时,我们需要反复触发,那么就可以用progressList来解决。

举个例子:

var a = $.Deferred();

a.done(function(x){console.log(x);}).done(function(x){console.log(x)});

a.resolve(1);

如果大家看了上一课的jQuery Deferred的源码,就知道,创建了一个新的延迟对象a,然后通过done方法添加了两个成功回调函数,最后通过resolve方法触发a的成功回调,因此会执行这两个成功回调函数,打印出两个1.

这时如果你再调用a.resolve(2);再次触发a的成功回调,不会打印出两个1.

但是progressList可以,

var b = $.Deferred();

b.progress(function(x){console.log(x);}).progress(function(x){console.log(x)});

b.notify(1);

b.notify(2);

第一个notify会打印出两个1,第二个notify会打印出两个2.

从上面的例子中,大家可以看出,doneList,failList触发一次状态后,就会结束了,你后面再次触发同样的状态,是不会执行回调函数的。但是progressList可以触发多次状态,也就意味着你只要调用notify,就会执行progress添加的回调函数。

jQuery1.8又对Deferred进行了重构,不过思路是一致的。

Promise/A隶属于Promise规范,而Promise规范则又隶属于CommonJS。

Promise/A规范大概是这样描述的:一个带有then方法的对象,它拥有3个状态,fulfilled,rejected,pending。then方法可以传入三个函数,一个是成功时执行的回调函数onFulfill,一个是失败时执行的回调函数onReject,一个是进行中执行的回调函数onNotify,它不会改变对象的状态(刚开始对象就处于pending,当执行成功回调函数onFulfill后,对象就会变成fulfilled状态,当执行失败回调函数onReject后,对象就会变成rejected状态,当执行进行中回调函数onNotify后,对象状态不会改变,还是pending状态)。这三个函数都是可选的,如果是非函数,就忽略掉。then方法会返回一个新的Promise对象,以便能够实现链式操作。

后来人们在Promise/A的规范上添加了更多的细节,形成了Promise/A+规范。现在市面上有三大Promise/A+库,分别是:Q,RSVP,when。其中,Q的微缩版被整进angular.js,RSVP被整进了ember.js。这两个库就是著名的MVVM库。后面的章节将会讲到这两个库,我也很期待。

js异步处理的前景

未来的javascript将支持yield生成器(generator),目前只有Firefox浏览器有,但是需要自己打开实验性开关。

<script type="text/javascript; version=1.7">    //这里改成1.8也行

  //这里面就可以使用yield了

</script>

此yield,可以让我们轻松的以同步的形式写出异步的代码。你只需要将它们放到某个函数体内。相应的库有:taskjs,gens,tamejs等。

有人对各种不同实现的异步库进行性能评测,基于原生生成器的库总体上占优势。yield语句比回调更能及时的工作,耗时更少。

但是在目前,实现生成器的代码量非常大,而实现Promise则相对轻松一些,因此Promise是当下最廉价的异步方案。

yield还没有真正的发展起来,因此不用精读。知道有这么一个东西就行。

下一课,将讲解Ajax,大家可以先去看一下Ajax Hacks这本书。

加油!

第三十四课:jQuery Deferred详解2的更多相关文章

  1. 第三十五课:Ajax详解

    一个完整的Ajax请求: var xhr = new (self.XMLHttpRequest || ActiveXObject)("Microsoft.XMLHTTP");   ...

  2. 第三十九课:requestAnimationFrame详解

    大家应该都知道,如果一个页面运行的定时器很多,无论你怎么优化,最后肯定会超过指定时间才能完成动画.定时器越多,延时越严重. 为此,YUI,kissy等采用中央队列的方式,将定时器减少至一个.浏览器厂商 ...

  3. NeHe OpenGL教程 第三十四课:地形

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  4. “全栈2019”Java第五十四章:多态详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

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

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

  6. Jquery Deferred 详解

    近期由于公司项目主要由我来负责前端,所以打算优化一下代码.在jquery 里面有个Deferred的对象.为了研究这个也看了不少资料,其中阮一峰的博客写的很详细,这里转载一下. 一.什么是deferr ...

  7. JAVA学习第三十四课 (经常使用对象API)—List集合及其子类特点

    整个集合框架中最经常使用的就是List(列表)和Set(集) 一.List集合 && Set的特点 Collection的子接口: 1.List:有序(存入和取出的顺序一致),元素都有 ...

  8. 潭州课堂25班:Ph201805201 django 项目 第三十四课 后台文章标签更新功能 ,创建功能实现(课堂笔记)

    g更改标签:,前台要向后台传来 id, name, 对标签进行校验:标签不能为空,标签是否已经存在, 流程: def put(self, request, tag_id): ''' 更改标签 :par ...

  9. python第三十四课——2.匿名函数配合容器函数的使用

    匿名函数配合容器函数的使用(了解) 1.匿名函数配合列表对象使用 lt=[lambda x:x**2,lambda x:x**3,lambda x:x**4] for i in lt: print(i ...

随机推荐

  1. Hadoop Browse the filesystem 无效处理

    当我们安装好并正常运行hdfs后输入http://xxxxxxxxx:50070会进入下图所示的页面. 其中Browse the filesystem 是查看文件系统的入口. 但是在发现这个链接一直无 ...

  2. 解决android的ListView嵌套在ScrollView中不能被滚动的问题

    使用滚动条容易带来一个后果,就是高度和宽度不受控制了, 之前就遇到一个已经有ScrollView的页面需要加个列表listView,然后就发现listView只看到前两行数据,下面的看不到,拉滚动条也 ...

  3. volatile 关键字

    就象大家更熟悉的const一样,volatile是一个类型修饰符(type specifier).它是被设计用来修饰被不同线程访问和修改的变量.如果没有volatile,基本上会导致这样的结果:要么无 ...

  4. 迅为iTOP-4412核心板调整电压

    本文转自:http://www.topeetboard.com iTOP-4412核心板使用的电源管理芯片是三星专门针对4412研发的S5M8767,8767提供9路BUCK和28路LDO输出,每路电 ...

  5. [麦先生]学习PDO循序渐进使用方式

    使用方式  特点一:支持跨数据库 1:首先实例化PDO,创建PDO对象的四个必备参数:host(哪一种类型的数据库,mysql/orcal/SQLserver等);dbname(数据库的名称);cha ...

  6. 边工作边刷题:70天一遍leetcode: day 76

    Count Univalue Subtrees 要点:检测条件比较有意思:因为可能的情况比较多,只要违反了任意一条就return False,所以可以只考虑False的情况,最后return True ...

  7. CSS 属性 :before && :after的用法,伪类和伪元素的区别

    一::before && :after的用法 :before 如同对伪元素的名称一样,:before 是用来给指定的元素的内容前面插入新的内容.举例说明: .before:before ...

  8. POJ 2253 Frogger -- 最短路变形

    这题的坑点在POJ输出double不能用%.lf而要用%.f...真是神坑. 题意:给出一个无向图,求节点1到2之间的最大边的边权的最小值. 算法:Dijkstra 题目每次选择权值最小的边进行延伸访 ...

  9. ssm中使用hibernate-validator验证BO

    目前比较流行的验证做法:前端jquery-form-validate + 后端hibernate-validate 在pom中添加相关jar: <!-- use hibernate-valida ...

  10. Android Activity的生命周期

    一.为什么要了解Activity的生命周期 activity is directly affected by its association withother activities, its tas ...