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 ...
随机推荐
- nmap使用方法
你是否曾想知道你所在局域网中哪些IP已经被使用了?还有哪些IP地址没有被使用?是否想知道某个IP地址下是什么系统…… 这些问题我们都可以使用一个nmap的工具解决,下面,就让我们开始了解nmap. ...
- Android开发艺术探索》读书笔记 (5) 第5章 理解RemoteViews
第5章 理解RemoteViews 5.1 RemoteViews的应用 (1)RemoteViews表示的是一个view结构,它可以在其他进程中显示.由于它在其他进程中显示,为了能够更新它的界面,R ...
- okhttp 常用使用方式 封装 演示
工具介绍 使用: AndroidStudio:[compile 'com.squareup.okhttp3:okhttp:3.4.2']和[compile 'com.zhy:okhttputils:2 ...
- jAVA EE里什么是链式调用
链式调用就是每次调用完了过后返回的是自己,比如Hibernate里面执行hql需要设置参数时,每次设置完参数可以继续使用点设置下一个参数http://blog.sina.com.cn/s/blog_4 ...
- Swift - 20 - 字典的基础操作
//: Playground - noun: a place where people can play import UIKit var dict = [1:"one", 2:& ...
- ubuntu远程连接
apt-cache search openssh-server //直接用apt-get install openssh-server安装.记不清包名字时可用apt-cache search o ...
- 【USACO 1.3.1】混合牛奶
[题目描述] 由于乳制品产业利润很低,所以降低原材料(牛奶)价格就变得十分重要.帮助梅丽乳业找到最优的牛奶采购方案. 梅丽乳业从一些奶农手中采购牛奶,并且每一位奶农为乳制品加工企业提供的价格是不同的. ...
- Android之声音管理器《AudioManager》的使用以及音量控制
以下为网上下载然后拼接-- Android声音管理AudioManager使用 手机都有声音模式,声音.静音还有震动,甚至震动加声音兼备,这些都是手机的基本功能.在Android手机中,我们同样可以通 ...
- openstack nova数据库计算结点IP地址
最近遇到一个问题就是在控制结点上查找nova数据库中 select * from compute_nodes\G;中出现IP地址一直是127.0.0.1不是计算结点的IP,就算修改成计算结点的IP,也 ...
- LINUX系统安装MYSQL命令,纯手打
1.下载安装包 wget http://cdn.mysql.com/archives/mysql-5.6/mysql-5.6.26-linux-glibc2.5-x86_64.tar.gz 2. ...