zoukankan      html  css  js  c++  java
  • jQuery使用(十二):工具方法之ajax的无忧回调(优雅的代码风格)

    • jQuery.ajax()方法的应用
    • jQuery.ajax()的无忧回调(优雅的代码风格)

     一、jQuery.ajax()方法的应用

    jQuery.ajax()实质上就是在ajax的基础上进行了封装,将参数设置,方法调用,数据传输,响应的回调函数等都封装到一个对象中,然后使用这个对象作为jQurey.ajax()的参数调用实现统一配置执行的效果。

    jQuery.ajax(object)中的object的常用属性及设置:

    • url:请求地址
    • type:HTTP的请求方法
    • success:请求成功的处理函数(响应的数据会被转换成对象传入处理函数)
    • error:当请求失败的处理函数,会传入一个提示对象,其中obj.status为状态码,obj.statusText表示状态说明。
    • complete:请求完成以后(无论成功还是失败)的处理函数
    • context:改变函数上下文
    • timeout:设置本地的请求超时时间(以毫秒计)。
    • async:请求采用异步还是同步执行(默认异步)
    • dataType:预期的服务器响应的数据类型(json)。

     1.Easy Mock模拟jQuery.ajax()请求:

     1 $.ajax({
     2     url:'https://easy-mock.com/mock/5c0b4a876162b83fe0a50cb9/person',
     3     type:"GET",
     4     success:function(res){
     5         $.each(res.data,function(index,ele){
     6             console.log(ele);
     7         })
     8     },
     9     error:function(e){
    10         if(e.status == 404){
    11             console.log("我找不到主人要的宝贝。。。哇呜。。。");
    12         }
    13     },
    14     complete:function(){
    15         console.log("我完成了任务,快夸我,夸我的人都长得好。");
    16     }
    17 });

    2.使用context改变函数执行的上下文示例:

     1 //html
     2 <div class="wrapper"></div>
     3 //js
     4 $.ajax({
     5     url:'https://easy-mock.com/mock/5c0b4a876162b83fe0a50cb9/person',
     6     type:"GET",
     7     success:function(res){
     8         console.log(this);////init [div.wrapper, prevObject: init(1), context: document, selector: ".wrapper"]
     9     },
    10     context:$('.wrapper'),
    11     complete:function(){
    12         console.log(this)//init [div.wrapper, prevObject: init(1), context: document, selector: ".wrapper"]
    13     }
    14 });

     二、jQuery.ajax()的无忧回调(优雅的代码风格)

    通过第一部分的分析,好像jQuery.ajax已经全部学会了,no...

    对于一个简单的网络请求来说,第一部分无可厚非已经足以,但是在实际开发中,复杂的需求伴随着的是复杂的代码结构和网络情况,如果存在多个网络请求嵌套请求的情况,代码会出现死亡三角的复杂区域,对于后期维护会造成非常大的麻烦。为了更友好的开发维护,jQuery.ajax提供了强大的解决方案,就是jQuery.ajax请求会返回一个Deferred.promise()方法,这个方法提供了友好的ajax不同完成状态的回调函数的添加接口。可能到这里你还不知道我在说什么,接下来看下面这个需求的由ajax产生的死亡三角和其解决方案的两份代码你就明白了,由于篇幅比较大,我将需求和死亡三角代码折叠,提供最后优雅的代码展示:

     1 <!-- 一、基础说明
     2 code/    code为0时表示正常状态,msg为Ok
     3 msg /    code为非0时表示异常状态,msg为error
     4 data/    接口返回实体数据
     5 二、实体对象
     6 power:
     7 名称    /    类型/        备注
     8 Power/    String/      权限
     9 movieList:
    10 名称      / 类型  /  备注
    11 name  /    String/    电影名字
    12 poster/    String/    电影封面
    13 id    /    String/    电影id
    14 movieInfo:
    15 名称           /    类型             /  备注
    16 name       /    String       /    电影名字
    17 poster     /    String       /    电影封面
    18 direct     /    String       /    导演
    19 screewriter/    Array<string>/    编剧
    20 mainActior /    Array<string>/    主演
    21 gut           /    String         /  剧情
    22 三、接口文档
    23 1.权限
    24 BaseUrl:https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie
    25 URL:/power
    26 Type:POST
    27 Request:
    28 名称        /   类型      / 备注
    29 Username/    String/    用户名
    30 Password/    String/    密码
    31 Response:
    32 {
    33     code:0
    34     msg:OK
    35     data:power
    36 }
    37 
    38 2.电影列表
    39 BaseUrl:https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie
    40 URL:/movieList
    41 Type:GET
    42 Response:
    43 {
    44     code:0
    45     msg:OK
    46     data:Array <movieList>
    47 } 
    48 
    49 3.电影详情
    50 BaseUrl:https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie
    51 URL:/movieInfo
    52 Type:GET
    53 Request:
    54 名称       /    类型      /  备注
    55 movieId/    Number/     电影的ID
    56 Response:
    57 {
    58     code:0
    59     msg:OK
    60     data:movieInfo
    61 }
    文档
     1 <style type="text/css" media="screen">
     2     *{
     3         padding: 0px;
     4         margin: 0px auto;
     5     }
     6     .tpl{
     7         display: none;
     8     }
     9     .wrapper{
    10         overflow: hidden;
    11         border: 2px solid black;
    12         width: 600px;
    13         margin: 100px auto 0px;
    14     }
    15     .movieSection{
    16         float: left;
    17         width: 180px;
    18         height: 180px;
    19         padding: 10px;
    20     }
    21     .movieSection img{
    22         width: 100%;
    23         height: 150px;
    24         cursor: pointer;
    25     }
    26     .movieSection h3{
    27         height: 30px;
    28     }
    29 </style>
    30 <div class="wrapper">
    31     <div class="tpl">
    32         <img src="">
    33         <h3 class="movieName"></h3>
    34     </div>
    35 </div>
    36 <script>
    37     //
    38     $.ajax({
    39         url:'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/power',
    40         type:"POST",
    41         data:{
    42             username:"cst",
    43             password:"123123"
    44         },
    45         success:function(res){
    46             if(res.data.power == 'root'){
    47                 //vip 网络地址发送请求
    48                 $.ajax({
    49                     url:'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/movieList',
    50                     type:'GET',
    51                     success:function(res){
    52                         var data = res.data;
    53                         var $Wrapper = $('.wrapper');
    54                         $.each(data,function(index,ele){
    55                             // ele.name ele.poste
    56                             var $MovieSection = $('.tpl').clone().removeClass('tpl').addClass('movieSection');
    57                             $MovieSection.data({id:ele.id}).on('click',function(){
    58                                 $.ajax({
    59                                     url:"https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/movieInfo",
    60                                     type:'GET',
    61                                     data:{
    62                                         movieId:$(this).data('id')
    63                                     },
    64                                     success:function(res){
    65                                         var data = res.data;
    66                                         var direct = data.direct;
    67                                         var gut = data.gut;
    68                                         var mainActor = data.mainActor;
    69                                         var screenWriter = data.screenwriter;
    70                                         var htmlStr = '<div class="mask">
    71                                             <p>导演:'+ direct +'</p>
    72                                             <p>主演:'+ mainActor.reduce(function(prev,curv){
    73                                                 prev += curv + "&nbsp;&nbsp;";
    74                                                 return prev;
    75                                             }) +'</p>
    76                                             <p>编剧:'+ screenWriter.reduce(function(prev,curv){
    77                                                 prev += curv + "&nbsp;&nbsp;";
    78                                                 return prev;
    79                                             }) +'</p>
    80                                             <p>剧情:'+ gut +'</p>
    81                                         </div>';
    82                                         console.log(htmlStr);
    83                                         $(htmlStr).appendTo('body')
    84                                             .css({position:'absolute',left:$(window).outerWidth()/2,bottom:100,400,marginLeft:-200,top:505});
    85                                     }
    86                                 });
    87                             }).children()
    88                                 .eq(0).attr('src',ele.poster)
    89                                     .next().text(ele.name);
    90                             $Wrapper.append($MovieSection);
    91                         });
    92                     }
    93                 });
    94             }else{
    95                 //非vip
    96             }
    97         }
    98     });
    99 </script>
    回调地狱

    通过上面的【回调地狱】就有一个值得思考的问题了,如何避免这种代码带来的负面影响呢?可以参考另一篇博客:jQuery使用():Deferred有状态的回调列表(含源码)如果要完整的解析整个jQuery.ajax解决这种【回调地狱】的问题就相当于要将jQuery.Deferred的实现机制全部解析一篇,所以这里就不再赘述了。用最简单的描述就是当通过jQuery.ajax()创建一个请求时,jQuery.ajax()会返回一个jQuery.Deferred对象,更准确的说是会返回Deferred.promise对象,这样就可以通过在外部接收这个对象,promise对象上包含了一系列的异步状态的回调函数的注册方法done、fail、progress、then。这些方法的具体使用参考前面那篇博客,下面我通过then方法来改造上面那段【回调地狱】的代码:

     1 $.ajax({
     2     url:'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/power',
     3     type:"POST",
     4     data:{
     5         username:"cst",
     6         password:"123123"
     7     }
     8 //请求会员资源--电影列表
     9 }).then(function(res){
    10     if(res.data.power == 'root'){
    11         //vip 网络地址发送请求
    12         return $.ajax({
    13             url:'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/movieList',
    14             type:'GET'
    15         });
    16     }
    17 //
    18 }).then(function(res){
    19     var data = res.data;
    20     var $Wrapper = $('.wrapper');
    21     var df = $.Deferred();
    22     $.each(data,function(index,ele){
    23         // ele.name ele.poste
    24         var $MovieSection = $('.tpl').clone().removeClass('tpl').addClass('movieSection');
    25         $MovieSection.data({id:ele.id})
    26             .on('click',function(){
    27                 df.resolve($(this));
    28             })
    29                 .children()
    30                     .eq(0).attr('src',ele.poster)
    31                         .next().text(ele.name);
    32         $Wrapper.append($MovieSection);
    33     });
    34     return df.promise();
    35 }).then(function(dom){
    36     return $.ajax({
    37         url:"https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/movieInfo",
    38         type:'GET',
    39         data:{
    40             movieId:dom.data('id')
    41         }
    42     })
    43 }).then(function(res){
    44     console.log(res);
    45     var data = res.data;
    46     var direct = data.direct;
    47     var gut = data.gut;
    48     var mainActor = data.mainActor;
    49     var screenWriter = data.screenwriter;
    50     var htmlStr = '<div class="mask">
    51         <p>导演:'+ direct +'</p>
    52         <p>主演:'+ mainActor.reduce(function(prev,curv){
    53             prev += curv + "&nbsp;&nbsp;";
    54             return prev;
    55         }) +'</p>
    56         <p>编剧:'+ screenWriter.reduce(function(prev,curv){
    57             prev += curv + "&nbsp;&nbsp;";
    58             return prev;
    59         }) +'</p>
    60         <p>剧情:'+ gut +'</p>
    61     </div>';
    62     console.log(htmlStr);
    63     $(htmlStr).appendTo('body')
    64         .css({position:'absolute',left:$(window).outerWidth()/2,bottom:100,400,marginLeft:-200,top:505});
    65 });

    上面改造后的代码也就是开发中需要遵循的单一职责原则。

  • 相关阅读:
    PowerDesigner_15连接Oracle11g,反向工程导出模型图
    angular学习
    GoEasy消息推送
    Spring 工作原理
    JAVA解析HTML,获取待定元素属性
    设计模式之工厂方法模式
    设计模式之单例模式
    通过Java代码获取系统信息
    centos7下NAT模式下设置静态ip
    关于在Spring项目中使用thymeleaf报Exception parsing document错误
  • 原文地址:https://www.cnblogs.com/ZheOneAndOnly/p/10549995.html
Copyright © 2011-2022 走看看