jquery Deferred对象的好处(一)
来源:互联网 发布:keras与tensorflow 编辑:程序博客网 时间:2024/05/18 02:46
jquery Deferred对象的好处 (一)
1、引子
先看一个普通的业务逻辑请求
$.ajax({ url:'test.htm', data:{ userId:'001', param1:"a1", param2:'a2' ... }, succsss:function(){ ... }});
这是一段普通的请求代码,里面携带了userId以及其他的一些业务参数。userId是用来识别用户身份的,几乎每个业务请求都要带上它。
现在为考虑到安全性将userId存在于服务器的session中(用户登录时生成),下次请求是浏览器只需cookies中的信息带过去就行了,而无需带上userId。
传统的网站session过期时往往要用户去重新登录,而现在产品经理改了需求,业务请求身份过期时不跳登录,而是激活身份,正常完成业务请求。
好!easy啦。。无非是再多发一个激活身份的请求(先叫他refreshUrl),上代码
//以ajax请求同步的方式实现var tokenResult=true;//代表身份是否过期的变量 function tokenRefresh(){ var result=false; $.ajax({ url:refreshUrl, ansy:false, data:{ param1:"a1", param2:'a2' ... }, succsss:function(){ if(sussess){ //刷新session result=true; return; } else { //error catch } //doSomethings.. } }); return result;}function doSomethings(){ $.ajax({ url:'test.htm', ansy:false, data:{ param1:"a1", param2:'a2' ... }, succsss:function(){ if(errorCode===-1){ //身份过期 tokenResult=false; return; } //doSomethings.. } });}doSomethings();if(!tokenResult&&tokenRefresh()){ //session过期时刷新session,再发一次请求 doSomethings();}
代码量是大了点但是勉强是可以使用的而且安全性也可以保证。过几天产品经理又来改需求了(又改需求。。),他说有时候发用户反馈业务请求时会出现几秒钟的空白时间,需要价格等待界面。说加就加,代码就这样写
//其他的不变无非就加个等待页面的显示和隐藏showWaitUI();//发起请求时显示等待页面,上面放个会转的菊花.giffunction doSomethings(){ $.ajax({ url:'test.htm', ansy:false, data:{ param1:"a1", param2:'a2' ... }, succsss:function(){ if(errorCode===-1){ //身份过期 tokenResult=false; return; } else if(success){ //doSomethings... hideWaitUI();//隐藏等待框 //执行正常的业务逻辑 } } });}doSomethings();if(!tokenResult&&tokenRefresh()){ //session过期时刷新session,再发一次请求 doSomethings();}
现在问题来了,当你运行调试时发现等待页面是出来了但是小菊花转不动了,一查发现是ajax同步请求阻塞了UI线程,那还有什么办法只好使用异步呗。
//修改代码function tokenRefresh(doSthFun){ $.ajax({ url:refreshUrl, ansy:false, data:{ param1:"a1", param2:'a2' ... }, succsss:function(){ if(sussess){ //刷新session,继续执行业务操作 doSthFun() } else { //error catch } //doSomethings.. } });}function doSomethings(){ $.ajax({ url:'test.htm', ansy:false, data:{ param1:"a1", param2:'a2' ... }, succsss:function(){ if(errorCode===-1){ //身份过期 tokenRefresh(doSomethings); return; } else if(success){ //doSomethings... hideWaitUI();//隐藏等待界面 //执行正常的业务逻辑 } } });}showWaitUI();//显示等待界面doSomethings();//执行业务操作
但是段代码嵌套调用逻辑性和可读性都很差,而且不安全,很容易发生死锁,从而陷入回调地狱,因此这里引出Deferred对象解决上述问题。
2、Deferred 对象的介绍
简单说,deferred对象就是jQuery的回调函数解决方案。在英语中,defer的意思是”延迟”,所以deferred对象的含义就是”延迟”到未来某个点再执行。
它解决了如何处理耗时操作的问题,对那些操作提供了更好的控制,以及统一的编程接口。
在高于1.5版本的jquery库中ajax请求返回的都是一个deferred对象,因此ajax请求的回调可以写成链式的形式
$.ajax({ url:'text.html'}).done(function(data){ //doSthings With success...}).fail(function(error){ //doSthings With fail...});
done()相当于success方法,fail()相当于error方法。采用链式写法以后,代码的可读性大大提高。
deferred对象的最大优点,就是它把这一套回调函数接口,从ajax操作扩展到了所有操作。也就是说,任何一个操作不管是ajax操作还是本地操作,也不管是异步操作还是同步操作都可以使用deferred对象的各种方法,指定回调函数。
//for example...//定义一个很耗时的操作函数var doSomethings=function(){ var tasks = function(){ if(succsee){ alert('success'); }else{ alert('fail'); } } setTimeOut(tasks,50000);}
如果我们将它作为指定函数,可以用$.when()实现。由于$.when()只支持deferred对象。因此需要改写上述代码为。
var doSomethings=function(){ // 新建一个deferred对象 var deferred= $.Deferred(); var tasks = function(){ if(succsee){ alert('success'); //设置执行状态为已完成,执行done回调 deferred.resolve(data); }else{ //设置执行状态为失败,执行fail回调 deferred.reject(data); alert('fail'); } } setTimeOut(tasks,50000); //调用deferred对象的promise方法,让执行状态不能再外部被改变 return deferred.promise();}$when(doSomethings()).done(function(data){ //dosomething with success...}).fail(function(){ //dosomething with fail...})
3、使用
根据deferred的知识,原来的业务操作请求代码可以改写成如下形式:
var deferred=$.Deferred(); // 新建一个Deferred对象function doSomethings(){ $.ajax({ url:'test.htm', ansy:false, data:{ param1:"a1", param2:'a2' ... }, succsss:function(data){ if(errorCode===-1){ //身份过期 deffered.resolve(false); return; } else if(success){ //doSomethings... hideWaitUI();//隐藏等待界面 //执行正常的业务逻辑 } deffered.resolve(true); }, error:function(){ deferred.reject(); } }); return deferred.promise();}showWatiUI();//显示等待界面$.when(doSomethings()).done(fuction(tokenResult){ if(!tokenResult){ tokenRefresh(); doSomethings(); }}).always(function(){ //无论成功失败读执行 hideWaitUI();});
那么问题也解决了,再次运行程序,会发现菊花已经可以转动了。
注:(如果想对deferred对象有更多的了解,请阅读阮一峰老师的《jQuery的deferred对象详解》)
http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html
- jquery Deferred对象的好处(一)
- jquery Deferred对象的好处(二)
- jQuery的deferred对象
- jquery 的deferred对象
- jQuery的deferred对象
- jQuery的Deferred对象
- jQuery的deferred对象
- jQuery的deferred对象
- jQuery的deferred对象
- jquery的deferred对象
- JQuery的Deferred对象
- jquery的Deferred的对象
- jQuery的deferred对象详解
- jQuery的deferred对象详解
- jQuery的deferred对象详解
- jQuery的deferred对象详解
- jQuery的deferred对象详解
- jQuery的deferred对象详解
- 踩坑系列之 memcache的有效期
- PS羽化N个像素后填充淡绿色
- Java线程池为何保持线程一直存在
- Rxjava之旅-初级篇
- ConcurrentHashMap以及CopyOnWrite容器浅谈
- jquery Deferred对象的好处(一)
- LeetCode(63) Unique Paths II
- 我对Linux和内核的理解
- static关键字
- eclipse下开发java web预备工作
- iOS中NSString 使用 copy 和 strong 修饰的区别详解
- leetcode submission/20161013(add digits)
- CSS中为了select下拉项目设置超链接
- Android Studio 使用小技巧和快捷键