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 ...
随机推荐
- VS项目属性配置实验过程
(原创,转载注明出处:http://www.cnblogs.com/binxindoudou/p/4017975.html ) 一.实验背景 cocos2d-x已经发展的相对完善了,从项目的创建.编译 ...
- Creating a simple static file server with Rewrite--reference
Today, I’d like to take a quick moment to demonstrate how to make a simple file server using Rewrite ...
- iOS开发UI篇-懒加载、重写setter方法赋值
一.懒加载 1.懒加载定义 懒加载——也称为延迟加载,即在需要的时候才加载(效率低,占用内存小).所谓懒加载,写的是其get方法. 注意:如果是懒加载的话则一定要注意先判断是否已经有了,如果没有那么再 ...
- iOS开发系列之运动事件
前面我们主要介绍了触摸事件以及由触摸事件引出的手势识别,下面我们简单介绍一下运动事件.在iOS中和运动相关的有三个事件:开始运动.结束运动.取消运动. 监听运动事件对于UI控件有个前提就是监听对象必须 ...
- 《Android开发艺术探索》读书笔记 (7) 第7章 Android动画深入分析
本节和<Android群英传>中的第七章Android动画机制与使用技巧有关系,建议先阅读该章的总结 第7章 Android动画深入分析 7.1 View动画 (1)android动画分为 ...
- retrofit2 okhttp3 RxJava butterknife 示例
eclipse的jar包配置 eclipse中貌似用不了butterknife buildToolsVersion "23.0.2" defaultConfig { applica ...
- Android MediaCodec 使用例子
Android MediaCodec 使用例子 下面的例子是使用MediaCodec 录制到文件的例子. 1 public class AvcEncoder { private MediaCodec ...
- ASPNET5的依赖注入
ASP.NET5设计的时候就是以DI为基础的,它可以利用内建的框架在Startup类的方法中,把依赖注入进去.应用服务也可以被配置的注入.默认的服务容器提供一些基本的功能,它并不打算代替现代主流的DI ...
- div 显示滚动条
overflow-x:auto 显示横向滚动条 overflow-y:hidden 隐藏纵向滚动条 引用此class,只显示横向的滚动条 .max{ margin:auto; overflow- ...
- 状态开关按钮(ToggleButton)及按钮(Swich)的使用
状态开关按钮(ToggleButton)和开关(Switch)也是由Button派生出来的,因此它们本质上都是按钮,Button支持的各种属性.方法也适用于ToggleButton和Switch.从功 ...