简介


  在jQuery1.5.0版本引入,为了实现Deferred对象,jQuery改写了ajax。是由jQuery.Deferred()方法创建的链式对象。

  $.Deferred在jQuery代码自身四处被使用(promise、DOM ready、Ajax、Animation)

  

  特性:使用Deferred对象可以添加多个回调函数; 延迟特性,处理耗时操作问题

  • register multiple callbacks into callback queues
  • invoke callback queues
  • relay the success or failure state of any synchronous or asynchronous function

主要源码


jQuery1.9.1源码如下:

jQuery.extend({

    Deferred: function( func ) {
var tuples = [
// action, add listener, listener list, final state
[ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
[ "notify", "progress", jQuery.Callbacks("memory") ]
],
state = "pending",
promise = {
state: function() {
.....
},
always: function() {
....
},
then: function( /* fnDone, fnFail, fnProgress */ ) {
           ....
},
// Get a promise for this deferred
// If obj is provided, the promise aspect is added to the object
promise: function( obj ) {
.....
}
},
deferred = {}; // Keep pipe for back-compat
promise.pipe = promise.then; // Add list-specific methods
jQuery.each( tuples, function( i, tuple ) {
  ...
deferred[ tuple[0] + "With" ] = list.fireWith;
}); // Make the deferred a promise
promise.promise( deferred ); // Call given func if any
if ( func ) {
func.call( deferred, deferred );
} // All done!
return deferred;
}, // Deferred helper
when: function( subordinate /* , ..., subordinateN */ ) {
    ....
    return deferred.promise();
  } });

Callbacks 是jQuery的回调对象,用于添加回调、删除回调、执行回调等

jQuery.Callbacks = function( options ) {// Actual Callbacks object
self = {
// Add a callback or a collection of callbacks to the list
add: function() {
...
},
// Remove a callback from the list
remove: function() {
  ....
},
       ....
// Call all the callbacks with the given arguments
fire: function() {
self.fireWith( this, arguments );
return this;
},
// To know if the callbacks have already been called at least once
fired: function() {
return !!fired;
}
}; return self;
};

 

methods


  jQuery下两个方法:

  

$.Deffered() ——创建Deffered对象,var deferred = $.Deffered();

$.when()——为多个操作指定回调函数

  

  Deffered对象包含如下方法:

deferred.always()——执行回调函数,不管deffered 对象是 状态resolved或者是rejected
           (即不管成功或者失败,对应ajax中complete)(关于执行状态看下一章节) deferred.done()——当Deferred对象状态为resolved时执行回调函数 deferred.fail()——当Deferred对象状态为rejected时执行回调函数 deferred.then()——执行回调函数,deferred 对象是 状态resolved或者是rejected 或者是 in progress
deferred.isRejected()——判断状态是否为rejected

deferred.isResolved()——判断状态是否为resolved

deffered.state()——判断当前状态
deferred.promise()——返回Deferred的promise对象

deferred.reject()——reject a deferred对象,即将状态转为rejected( with the given args.)

deferred.rejectWith()——与上面reject的区别:with the given context and args. 下面类似

deferred.resolve()——即将状态转为resolve
              
deferred.resolveWith()——
deferred.notify()——call the progressCallbacks  

deferred.notifyWith()——  
 
 
deferred.pipe()——过滤参数
 

一般done/resolve fail/reject progress/notify 对应使用


执行状态


  Deffered对象三种执行状态: resolved(已完成)、未完成、rejected(失败)

  1. 如果执行状态是resovled,Deffered对象会立刻调用done()方法指定的回调函数

  2. 如果执行状态是rejected,Deffered对象会立刻调用fail()方法指定的回调函数

  3.  如果执行状态是未完成,Deffered对象会继续等待或者是调用progress()方法指定的回调函数

ajax及简单链式操作


eg:

ajax方式:

$.ajax("test.jsp").success(function(result){alert("success! data is :"+result);})  
.error(function(){alert("Error")})
           .complete(function(){alert("complete!")}); 或者: $.ajax({
url:"test.jsp",
success:function(result){alert("success! data is :"+result);},
     error: function(){alert("Error!");},
  complete:function(){alert("complete!")},
});

使用Deferred:

由于$.ajax 方法和$.get方法返回的是jqXHR对象(源自Deferred对象)因而上面的操作可以以下面的方式实现。

    $.ajax("test.jsp").done(function(result){alert("success! data is :"+result);})
.fail(function(){alert("Error")})
             .always(function(){alert("finished");});

注意:$.ajax()中jqXHR.success(), jqXHR.error(), jqXHR.complete(), 在jquery 1.8中已经弃用,应该使用done(),fail()和always()

done/resolve   fail/reject   progress/notify


done/resolve

var dfd = $.Deferred();

dfd.done(function(){
console.log("###############")
}); $("button").on("click",function(){
dfd.resolve();
});

点击按钮,输出  ###############

fail/reject

var dfd = $.Deferred();

dfd.fail(function(){
console.log("###############")
}); $("button").on("click",function(){
dfd.reject();
});

点击按钮,输出  ###############

progress/notify

eg1:

var dfd = $.Deferred();

dfd.progress(function(){
console.log("###############")
}); $("button").on("click",function(){
dfd.notify();
});

点击按钮,输出  ###############

eg2:使用notify间隔的执行回调函数

var dfd = $.Deferred();

dfd.progress(function(){
console.log("###############");
}); $("button").on("click",function(){
setInterval(function(){
dfd.notify();
},1000); });

点击按钮,每1s输出一次##################

执行多个回调函数


eg1:

    $.ajax("test.jsp").done(function(){console.log("the first callback");})
.done(function(){console.log("the second callback");})
.done(function(){console.log("the third callback");})
.fail(function(){console.log("Error")}); 或者: $.ajax("test.jsp").success(function(){console.log("the first callback");})
           .success(function(){console.log("the second callback");})
           .success(function(){console.log("the third callback");})
           .error(function(){console.log("Error")});

输出:

the first callback
the second callback
the third callback

eg2:

deferred对象的done方法定义如下:deferred.done( doneCallbacks [, doneCallbacks ] ) 可以传入 array of functions

success也可达到相同效果,但是已弃用不建议使用

     $.ajax("test.jsp").done([f1,f2,f3],[f2,f3])
.done(function(){console.log("the fourth callback");})
.fail(function(){alert("Error")});
function f1(){
console.log("the first callback");
}
function f2(){
console.log("the second callback");
}
function f3(){
console.log("the third callback");
}

输出结果如下:

the first callback
the second callback
the third callback
the second callback
the third callback
the fourth callback

eg3: 使用jQuery.Deferred()创建Deferred对象

简单使用done方法和resolve方法

function f1(){
console.log("the first callback");
}
function f2(){
console.log("the second callback");
}
function f3(){
console.log("the third callback");
} var dfd = $.Deferred();
dfd.done([f1,f2,f3],[f2,f3])
.done(function(){console.log("finished");});
$("button").on("click",function(){
dfd.resolve();
});

点击button,输出:

the first callback
the second callback
the third callback
the second callback
the third callback
finished

eg4. 给resolve添加args

function f1(arg){
console.log(arg+"the first callback");
}
function f2(arg){
console.log(arg+"the second callback");
}
function f3(arg){
console.log(arg+"the third callback");
} var dfd = $.Deferred();
dfd.done([f1,f2,f3],[f2,f3])
.done(function(){console.log("finished");})
.always(function(arg){console.log(arg+"end");}); $("button").on("click",function(){
dfd.resolve("###############");
});

输出如下:

###############the first callback
###############the second callback
###############the third callback
###############the second callback
###############the third callback
finished
###############end

then和pipe


 pipe

使用pipe可以过滤参数,但是jQuery 1.8后已经启用pipe方法,建议使用then

pipe方法定义为:deferred.pipe( [doneFilter ] [, failFilter ] [, progressFilter ] )    returns a new promise

eg1:一次性定义done fail 和progress

function f1() {
console.log('done');
}
function f2() {
console.log('fail');
}
function f3() {
console.log('progress');
}
var deferred = $.Deferred();
deferred.pipe(f1, f2, f3);
$("button").on("click",function(){
deferred.reject();
});

点击按钮,输出 fail, 可以根据需要修改deferred.reject 为resolve或者是notify

eg2:

var dfd = $.Deferred();
dfd.pipe(function(arg){return "(*^__^*)"+arg;}); dfd.done(function(arg){
console.log(arg)
}); $("button").on("click",function(){
dfd.resolve("###############");
});

点击按钮输出:

(*^__^*)###############

eg3:

var dfd = $.Deferred();
argFilter = dfd.pipe(null, function(arg){return "(*^__^*)"+arg;}); argFilter.fail(function(arg){
console.log(arg)
}); $("button").on("click",function(){
dfd.reject("###############");
});

输出结果同上

 then 

deferred.then( [doneFilter ] [, failFilter ] [, progressFilter ] )

function f1() {
console.log('done');
}
function f2() {
console.log('fail');
}
function f3() {
console.log('progress');
}
var deferred = $.Deferred();
deferred.then(f1, f2, f3);
$("button").on("click",function(){
deferred.reject();
});

效果同pipe

 when为多个操作指定回调函数


jQuery.when(deferreds);

如果传入单个deferred, 返回promise对象,后面可以链式添加then等方法

如果传入多个deferred,返回a new master deferred对象,该对象集合所有deferred对象的状态,如果所有deferred对象是resollve则结果是resolve,如果有一个是reject则结果是reject

eg1:

$.when($.ajax("test.jsp")).done(function(){console.log("done");});

结果:

GET http://localhost:8080/javascript/jQuery/test.jsp  200 OK 83ms    

done

eg2:

function f1() {
console.log('done');
}
function f2() {
console.log('fail');
}
function f3() {
console.log('progress');
}
$.when($.ajax("test.jsp")).then(f1,f2,f3);

结果同上

eg3:

$.when($.ajax("test.jsp"),$.ajax("demo.jsp")).done(function(){console.log("done");});

结果:

GET http://localhost:8080/javascript/jQuery/test.jsp  200 OK 83ms    

GET http://localhost:8080/javascript/jQuery/demo.jsp   200 OK 460ms    

done

eg4:

 <style>
div {
height: 50px;
width: 50px;
float: left;
margin-right: 10px;
display: none;
background-color: #090;
}
</style>
<button>button</button>
<div></div>
<div></div>
<div></div>
<div></div>
var effect = function() {
return $( "div" ).fadeIn( 800 ).delay( 1200 ).fadeOut();
}; $( "button" ).on( "click", function() {
$.when( effect() ).done(function() {
console.log("finished");
});
});

effect()方法执行完后输出 finished;

.promise()


.promise([type][,target])  return a promise object   当所有与其相关的action结束后变为resolve状态

(The .promise() method returns a dynamically generated Promise that is resolved once all actions of a certain type bound to the collection, queued or not, have ended.)

eg1:

var button = $( "<button>" );
button.promise().done(function( arg ) {
console.log( this === button && arg === button ); //true
});

eg2:

 <style>
div {
height: 50px;
width: 50px;
float: left;
margin-right: 10px;
display: none;
background-color: #090;
}
</style>
<button>button</button>
<div></div>
<div></div>
<div></div>
<div></div>
$( "button" ).on( "click", function() {

  $( "div" ).each(function( i ) {
$( this ).fadeIn().fadeOut( 1000 * ( i + 1 ) );
}); $( "div" ).promise().done(function() {
console.log("finished");
});
});

animation结束后输出finished,效果等价于when 中的eg4

相关:http://api.jquery.com/category/deferred-object/

     http://www.cnblogs.com/littledu/articles/2811728.html

   http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html

jQuery deferred学习笔记的更多相关文章

  1. jQuery源代码学习笔记_工具函数_noop/error/now/trim

    jQuery源代码学习笔记_工具函数_noop/error/now/trim jquery提供了一系列的工具函数,用于支持其运行,今天主要分析noop/error/now/trim这4个函数: 1.n ...

  2. jQuery的学习笔记4

    JQuery学习笔记3 2.9属性选择器 属性选择器就是根据元素的属性和属性值作为过滤条件,来匹配对应的DOM元素.属性选择器一般都以中括号作为起止分界符 它的形式如下: [attribute] [a ...

  3. jQuery的学习笔记2

    jQuery学习笔记 Day two Chapter two 选择器 类选择器 语法结构:$(“.classname”) javascript里面没有类选择器所以这个时候使用jQuery会更加的简便 ...

  4. jQuery的学习笔记

    JQuery学习笔记 Chapter one初识jQuery 1.2测试jQuery 在jQuery库中,$是jQuery的别名,如:$()相当于jQuery() 注意:在使用JQuery进行开发的时 ...

  5. jQuery 基础学习笔记总结(一)

    Jquery 学习笔记 总结 感想: 此前在做站点时用到过jquery相关,特别是Ajax相关技术.但是并没有系统的进行学习和了解Jquery的强大的功能,趁这几天跟着资料基本的了解下Jquery的特 ...

  6. Jquery Mobile 学习笔记(一)

    1.模拟器,IOS:XCODE GENYMOTION  ANDROID:ECLIPSE GENYMOTION 2.jquery mobile data-role=page 代表一个页面 data-po ...

  7. 【jQuery UI 1.8 The User Interface Library for jQuery】.学习笔记.4.Tabs控件

    之前,我们已经介绍了 jQuery UI 库,CSS 框架.下面,我们将学习这些有增强可视化效果,高度可配置的用户交互组件. Tab 的特性是,点击 tab 后,会高亮该 tab,并显示他的关联con ...

  8. Jquery mobile 学习笔记

    最近学习移动开发,接触到了phonegap,然后又需要开始学习jquery mobile.掌握两者是开发轻应用的前提 在学习jquery mobile中,遇到了许多问题让初学者很是头疼,无意间找到这个 ...

  9. jQuery api 学习笔记(1)

      之前自己的jquery知识库一直停留在1.4的版本,而目前jquery的版本已经更新到了1.10.2了,前天看到1.10中css()竟然扩充了那么多用法,这2天就迫不及待的更新一下自己的jquer ...

随机推荐

  1. Android设置虚线、圆角、渐变

    有图又真相,先上图再说. 点击效果: 设置虚线: <?xml version="1.0" encoding="utf-8"?> <shape  ...

  2. C/C++ Linux 程序员必须了解的 10 个工具

    1. 基本命令http://mally.stanford.edu/~sr/computing/basic-unix.htmlhttp://pangea.stanford.edu/computing/u ...

  3. Android省电开发 浅析

    相信对于Android App省电的开发,一切性能优化都可以达到App的省电开发,所以一个省电的Android应用,性能优化占据很重要的位置.除此之外整理了几点关于Android应用省电的开发技巧. ...

  4. linux command cp.

    Examples cp file1.txt newdir Copies the file1.txt in the current directory to the newdir subdirector ...

  5. Swift - 24 - switch语句的高级用法

    //: Playground - noun: a place where people can play import UIKit // 对区间进行判断 var score = 90 switch s ...

  6. java测试1

    发大水 package com.java1234.activiti.variable; import java.util.Date; import java.util.HashMap; import ...

  7. _Obj* __STL_VOLATILE* __my_free_list

    今天在读<STL源码剖析>空间配置器第二级时看到了这句,有点不解,于是查阅后知: obj后面是个指针 STL_VOLATILE也应该是个类型定义的吧,程序中应该有define来对它定义.所 ...

  8. C文件函数总结

    1.fopen(打开文件) 表头文件 #include<stdio.h> 定义函数 FILE *fopen(const char * path,const char * mode); pa ...

  9. 【USACO 3.1.1】最短网络

    [描述]      农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的场.当然,他需要你的帮助.     约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共 ...

  10. 疯狂学习java web2(css)

    CSS应该是样式描述的意思,定义如下: 什么是 CSS? CSS 指层叠样式表 (Cascading Style Sheets) 样式定义如何显示 HTML 元素 样式通常存储在样式表中 把样式添加到 ...