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 ...
随机推荐
- Android设置虚线、圆角、渐变
有图又真相,先上图再说. 点击效果: 设置虚线: <?xml version="1.0" encoding="utf-8"?> <shape ...
- C/C++ Linux 程序员必须了解的 10 个工具
1. 基本命令http://mally.stanford.edu/~sr/computing/basic-unix.htmlhttp://pangea.stanford.edu/computing/u ...
- Android省电开发 浅析
相信对于Android App省电的开发,一切性能优化都可以达到App的省电开发,所以一个省电的Android应用,性能优化占据很重要的位置.除此之外整理了几点关于Android应用省电的开发技巧. ...
- linux command cp.
Examples cp file1.txt newdir Copies the file1.txt in the current directory to the newdir subdirector ...
- Swift - 24 - switch语句的高级用法
//: Playground - noun: a place where people can play import UIKit // 对区间进行判断 var score = 90 switch s ...
- java测试1
发大水 package com.java1234.activiti.variable; import java.util.Date; import java.util.HashMap; import ...
- _Obj* __STL_VOLATILE* __my_free_list
今天在读<STL源码剖析>空间配置器第二级时看到了这句,有点不解,于是查阅后知: obj后面是个指针 STL_VOLATILE也应该是个类型定义的吧,程序中应该有define来对它定义.所 ...
- C文件函数总结
1.fopen(打开文件) 表头文件 #include<stdio.h> 定义函数 FILE *fopen(const char * path,const char * mode); pa ...
- 【USACO 3.1.1】最短网络
[描述] 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的场.当然,他需要你的帮助. 约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共 ...
- 疯狂学习java web2(css)
CSS应该是样式描述的意思,定义如下: 什么是 CSS? CSS 指层叠样式表 (Cascading Style Sheets) 样式定义如何显示 HTML 元素 样式通常存储在样式表中 把样式添加到 ...