jQuery使用(十二):工具方法之ajax的無憂回調(優雅的代碼風格)

  • jQuery.ajax()方法的應用
  • jQuery.ajax()的無憂回調(優雅的代碼風格)

 1、jQuery.ajax()方法的應用

jQuery.ajax()實質上就是在ajax的基礎上進行了封裝,將參數設置,方法調用,數據傳輸,響應的回調函數等都封裝到一個對象中,而後使用這個對象做爲jQurey.ajax()的參數調用實現統一配置執行的效果。css

jQuery.ajax(object)中的object的經常使用屬性及設置:html

  • url:請求地址
  • type:HTTP的請求方法
  • success:請求成功的處理函數(響應的數據會被轉換成對象傳入處理函數)
  • error:當請求失敗的處理函數,會傳入一個提示對象,其中obj.status爲狀態碼,obj.statusText表示狀態說明。
  • complete:請求完成之後(不管成功仍是失敗)的處理函數
  • context:改變函數上下文
  • timeout:設置本地的請求超時時間(以毫秒計)。
  • async:請求採用異步仍是同步執行(默認異步)
  • dataType:預期的服務器響應的數據類型(json)。

 1.Easy Mock模擬jQuery.ajax()請求: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改變函數執行的上下文示例:json

 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 });

 2、jQuery.ajax()的無憂回調(優雅的代碼風格)

經過第一部分的分析,好像jQuery.ajax已經所有學會了,no...promise

對於一個簡單的網絡請求來講,第一部分無可厚非已經足以,可是在實際開發中,複雜的需求伴隨着的是複雜的代碼結構和網絡狀況,若是存在多個網絡請求嵌套請求的狀況,代碼會出現死亡三角的複雜區域,對於後期維護會形成很是大的麻煩。爲了更友好的開發維護,jQuery.ajax提供了強大的解決方案,就是jQuery.ajax請求會返回一個Deferred.promise()方法,這個方法提供了友好的ajax不一樣完成狀態的回調函數的添加接口。可能到這裏你還不知道我在說什麼,接下來看下面這個需求的由ajax產生的死亡三角和其解決方案的兩份代碼你就明白了,因爲篇幅比較大,我將需求和死亡三角代碼摺疊,提供最後優雅的代碼展現:服務器

 1 <!-- 1、基礎說明
 2 code/    code爲0時表示正常狀態,msg爲Ok
 3 msg /    code爲非0時表示異常狀態,msg爲error
 4 data/    接口返回實體數據
 5 2、實體對象
 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 3、接口文檔
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,width: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,width:400,marginLeft:-200,top:505});
65 });

上面改造後的代碼也就是開發中須要遵循的單一職責原則。app

相關文章
相關標籤/搜索