jQuery deferred学习笔记
简介
在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学习笔记的更多相关文章
- jQuery源代码学习笔记_工具函数_noop/error/now/trim
jQuery源代码学习笔记_工具函数_noop/error/now/trim jquery提供了一系列的工具函数,用于支持其运行,今天主要分析noop/error/now/trim这4个函数: 1.n ...
- jQuery的学习笔记4
JQuery学习笔记3 2.9属性选择器 属性选择器就是根据元素的属性和属性值作为过滤条件,来匹配对应的DOM元素.属性选择器一般都以中括号作为起止分界符 它的形式如下: [attribute] [a ...
- jQuery的学习笔记2
jQuery学习笔记 Day two Chapter two 选择器 类选择器 语法结构:$(“.classname”) javascript里面没有类选择器所以这个时候使用jQuery会更加的简便 ...
- jQuery的学习笔记
JQuery学习笔记 Chapter one初识jQuery 1.2测试jQuery 在jQuery库中,$是jQuery的别名,如:$()相当于jQuery() 注意:在使用JQuery进行开发的时 ...
- jQuery 基础学习笔记总结(一)
Jquery 学习笔记 总结 感想: 此前在做站点时用到过jquery相关,特别是Ajax相关技术.但是并没有系统的进行学习和了解Jquery的强大的功能,趁这几天跟着资料基本的了解下Jquery的特 ...
- Jquery Mobile 学习笔记(一)
1.模拟器,IOS:XCODE GENYMOTION ANDROID:ECLIPSE GENYMOTION 2.jquery mobile data-role=page 代表一个页面 data-po ...
- 【jQuery UI 1.8 The User Interface Library for jQuery】.学习笔记.4.Tabs控件
之前,我们已经介绍了 jQuery UI 库,CSS 框架.下面,我们将学习这些有增强可视化效果,高度可配置的用户交互组件. Tab 的特性是,点击 tab 后,会高亮该 tab,并显示他的关联con ...
- Jquery mobile 学习笔记
最近学习移动开发,接触到了phonegap,然后又需要开始学习jquery mobile.掌握两者是开发轻应用的前提 在学习jquery mobile中,遇到了许多问题让初学者很是头疼,无意间找到这个 ...
- jQuery api 学习笔记(1)
之前自己的jquery知识库一直停留在1.4的版本,而目前jquery的版本已经更新到了1.10.2了,前天看到1.10中css()竟然扩充了那么多用法,这2天就迫不及待的更新一下自己的jquer ...
随机推荐
- (五)带属性值的ng-app指令,实现自己定义模块的自己主动载入
如今我们看下怎样使用带属性值的ng-app命令,让ng-app自己主动载入我们自己定义的模块作为根模块. <!DOCTYPE html> <html> <head> ...
- How To Cluster Rabbit-MQ--reference
Foreword This explanation of clustering Rabbit-MQ assumes that you’ve had some experience with Rabbi ...
- chmod -x chmod的N种解法
声明:该文章摘自陈皓的酷壳. 问题: 如果某天你的Unix/Linux系统上的chomd命令被某人去掉了x属性(执行属性),那么,你如何恢复呢? 参考答案: 1)重新安装.对于Debian的系统: s ...
- WebView使用详解(一)——Native与JS相互调用(附JadX反编译)
念念不忘,必有回响,永远坚持你所坚持的! 一直在用WebView,还没有系统的总结过它的用法,下面就系统的总结下,分享给大家 一.基本用法 1.加载在线URL void loadUrl(String ...
- uva 11324 The Largest Clique (Tarjan+记忆化)
/*每个环 要么不选 要么全选 可缩点 就得到一个GAD图 然后搞搞算出最大路径*/ #include<iostream> #include<cstdio> #include& ...
- IIS 配置好了,为什么网站打开一片空白?
方法如下: 进入:控制面板 - 卸载程序 - 打开或关闭Windows功能 如果访问任何不存在页面或页面出错时空白: Internet 信息服务 - 万维网服务 - 常见 HTTP 功能 - HTTP ...
- Dedecms当前位置{dede:field name='position'/}修改
这个实在list_article.htm模板出现的,而这个模板通过loadtemplage等等一系列操作是调用的include 下的arc.archives.class.php $this->F ...
- 【转】 分析iOS Crash文件:符号化iOS Crash文件的3种方法
当你的应用提交到AppStore或者各个渠道之后,请问你多久会拿到crash文件?你如何分析crash文件的呢? 上传crash文件 你的应用应当有模块能够在应用程序crash的时候上传crash信息 ...
- nodejs新手教程中upload file的问题
可参见: http://cnodejs.org/topic/50234890f767cc9a51f88481 request.setEncoding("utf8");应注释掉.
- Hibernate 事件监听
事件监听是JDK中常见的一种模式. Hibernate中的事件监听机制可以对Session对象的动作进行监听,一旦发生了特殊的事件,Hibernate就会调用监听器类中的事件处理方法.在某些功能的设计 ...