jQuery的Deferred对象,Promise对象
2015-06-23 22:22
661 查看
Ajax
Ajax
Ajax是实现异步操作的技术,用于创建快速动态网页的技术。可以在不重新加载整个网页的情况下,对网页的某部分进行更新。传统的网页(不使用AJAX)如果需要更新内容,必须重载整个网页页面。
没有Deferred对象的ajax
$.ajax({url:'xxx',
success:function(){}
error:function(){}
})
如果在要实现多个ajax的操作,那么就要在success:function(){}里面再次嵌套$.ajax({});方法。不可以链式操作。如果多层回调的话,那么代码不美观,可读性也差。
基于这样的背景,jQuery1.5之后引入了Deferred对象,Deferred对象就是jQuery的回调函数的解决方案。
Deferred对象和promise对象都是用来管理异步操作,是对ajax过程的一种抽象。从程序的角度来减少回调嵌套。
Deferred对象
jQuery1.5引入Deferred对象之后,可以实现链式操作写法。$.ajax('/xxx').success(function(){}).fail(function(){})
它定义了两种基本状态:resolved和rejected,然后定义了三个方法success,fail,always来定义当deferred对象从初始状态转换到两种基本状态时候应该调用哪些函数。最后提供了reject/rejectWith,resolve/resolveWith来改变deferred对象的状态,以便出发对应的回调函数。
如果ajax操作成功后,除了原来的回调函数,我还想再运行一个回调函数,直接把它加在后面就行了。
$.ajax("test.html")
.done(function(){
alert("哈哈,成功了!");}
)
.fail(function(){
alert("出错啦!");
})
.done(function(){
alert("第二个回调函数!");}
);
$.when()
对Promise对象也适用。如果想为多个操作添加一个回调函数,Deferred对象也提供了相应的方法,也就是$.when()方法。
$.when($.ajax("test1.html"),
$.ajax("test2.html"))
.done(function(){alert("哈哈,成功了!");
})
.fail(function(){alert("出错啦!");
});
这段代码的意思是,先执行两个操作$.ajax("test1.html")和$.ajax("test2.html"),如果成功了,就运行done()指定的回调函数;如果有一个失败或都失败了,就执行fail()指定的回调函数。
deferred对象的最大优点,就是它把这一套回调函数接口,从ajax操作扩展到了所有操作。也就是说,任何一个操作,不管是ajax操作还是本地操作,也不管是异步操作还是同步操作----都可以使用deferred对象的各种方法,指定回调函数。
比如,
varwait=function(){
vartasks=function(){
alert("执行完毕!");
};
setTimeout(tasks,5000);
};
$.when(wait())
.done(function(){alert("哈哈,成功了!");
})
.fail(function(){
alert("出错啦!");});
但是,when的参数只能是deferred对象,对wait进行改写。
vardtd=$.Deferred();
//新建一个deferred对象
varwait=function(dtd){
vartasks=function(){
alert("执行完毕!");
dtd.resolve();//改变deferred对象的执行状态
};
setTimeout(tasks,5000);
returndtd.promise();
};
这里有两个地方需要注意。首先,最后一行不能直接返回dtd,必须返回
其次,当操作完成后,必须手动改变Deferred对象的执行状态,否则回调函数无法触发。
最后别忘了,修改完wait之后,调用的时候就必须直接传入dtd参数。
$.when(wait(dtd))
.done(function(){alert("哈哈,成功了!");
})
.fail(function(){
alert("出错啦!");});
$.then()
对Promise对象也适用。用于给一个deferred对象添加监听器。该方法接受两个参数:
deferred.then(doneCallbacks,failCallbacks)
doneCallbacks:一个函数,或者是一组函数,在deferred被实现时调用
failCallbacks:一个函数,或者是一组函数,在deferred被拒绝时调用
例子:
Js代码
$.get("test.php").then(
function(){alert("$.getsucceeded");},
function(){alert("$.getfailed!");}
);
deferred.then()提供了一种方便的写法,让一个deferred在实现或者被拒绝时的监听函数可以写在一个api中。
Promise对象
Promise对象其实就是deferred对象的特例,因为Promise对象不能更改异步状态,而deferred对象可以。promise方法已经被混入deferred对象了,但是deferred对象的一些方法没有在promise中,主要就是触发状态转换和函数回调的几个方法比如reject/rejectWith。
所以promise能做的deferred都能做到,但是deferred能触发状态转换确实promise做不到的。所以使用promise方法返回promise对象可以防止被其他人改变自己的状态,他们只能通过promise来注册回调,但是不能通过promise来改变状态。
promise对象常见的方法有三个:done,fail,then。
其它的方法就不要去记了,jQuery这里的接口方法太多了,在我看来挺啰嗦的,就跟早期的事件方法绑定一样,live,delegate,bind,最终不是都归为on来管了么。
代码示例,如下:
1.DOM使用Promise方法:
varbox=$('#box');
box.promise().done(function(ele){
console.log(ele);//jQuerybox
});
2.Ajax使用Promise方法(默认返回一个Promise对象,所以可以不必显式调用Promise方法):
$.post('/',{}).done(function(data){
console.log('请求成功');
}).fail(function(){
console.log('请求错误');
});
Deferred对象和Promise对象
promise对象常见的方法有三个:done,fail,then。对于deferred对象呢,也就是使用$.Deferred()方法,以及$.when()等方法创造出来的对象,有如下的常用方法:
resolve,reject,notify;
done,fail,progress;
另外还有promise、then和always方法。
之所以这么排版,是因为他们是对应的,也就是说:resolve方法会触发done的回调执行,reject会触发fail的回调,notify会触发progress的回调。
直接看代码:
varwait=function(ms){
vardtd=$.Deferred();
setTimeout(dtd.resolve,ms);
//setTimeout(dtd.reject,ms);
//setTimeout(dtd.notify,ms);
returndtd.promise();//此处也可以直接返回dtd
};
wait(2500).done(function(){
console.log('haha,师太,你可让老衲久等了');
}).fail(function(){
console.log('失败了');
}).progress(function(res){
console.log('等待中...');
});
我们看到了,上面的代码中,在wait函数中,返回的是个Promise对象,而不是deferred对象。
要知道,Promise对象是没有resolve,reject,notify等方法的,也就意味着,你无法针对Promise对象进行状态更改,只能在done或fail中进行回调配置。所以,你如果这么调用wait(2500).resolve()将会报错,因为wait(2500)返回的是个Promise对象,不存在resolve方法。
但是,这么做,有个好处,我们把dtd这个deferred对象放在了wait函数中,作为了局部变量,避免了全局的污染;进一步通过Promise方法,转化dtd这个deferred对象为Promise对象,避免了函数wait外部可能发生的状态更改(假如我们确实有这个需求)。
相关文章推荐
- JQuery中$.ajax()方法参数详解
- Jquery操作Json数组
- jQuery Validate验证框架详解
- jquery如何获取元素的滚动高度
- Jquery autocomplete 下拉项显示图片
- jQuery 参考手册 - DOM 元素方法
- jQuery 核心 - jQuery() 方法
- jQuery 数据操作函数
- jQuery CSS 操作函数
- jQuery 属性操作方法
- jQuery 文档操作方法
- jQuery 事件方法
- jQuery 选择器
- jQuery 遍历函数
- 评分插件 jQuery raty的使用
- jquery的父子兄弟节点查找示例代码
- jquery easyui 多选下拉框的实现
- 【收藏】介绍一款jQuery插件:Fullpage.js
- 探索高效jQuery的奥秘
- Jquery EasyUI +Ajax +Json +一般处理程序 实现数据的前台与后台的交互 --- 善良公社项目