在實際的項目裏,ajax的應用頻率很高,因此儘管jquery或者其餘的一些相似的js庫作了很是不錯的封裝,仍然有進一步封裝簡化的空間和必要jquery
舉一個例子,好久好久之前,個人ajax是這麼寫的:ajax
$.ajax({ url: 'www.baidu.com/getInfo', type: 'POST', data: { name: 'jack', age: 18 }, dataType: 'json', success: function(resp){ // callback }, error: function(err){ // error code } });
乍一看挺好沒啥問題,可是其實success回調裏的邏輯可能很複雜,甚至可能會出現ajax回調裏再放一個ajax的狀況,那這種寫法就很糟糕了,全都雜糅在一塊兒json
能夠進行一個簡單的封裝,這在以前Deferred對象的隨筆裏已經有提到跨域
function ajax(url, param, type) { // 利用了jquery延遲對象回調的方式對ajax封裝,使用done(),fail(),always()等方法進行鏈式回調操做 // 若是須要的參數更多,好比有跨域dataType須要設置爲'jsonp'等等,也能夠不作這一層封裝,仍是根據工程實際狀況判斷吧,重要的仍是鏈式回調 return $.ajax({ url: url, data: param || {}, type: type || 'GET' }); } // 鏈式回調 ajax('www.baidu.com/getInfo').done(function(resp) { // 成功回調 }).fail(function(err) { // 失敗回調 });
可是雖然作到這一步了,問題仍是會來,好比我司,成功的回調裏還有一層邏輯判斷,像這樣:jsonp
// 我司ajax返回的json數據格式 // 當result爲false時,msg中每每有錯誤信息 { result: true, data: { name: 'jack' }, msg: null } ajax('www.baidu.com/getInfo').done(function(resp) { // 成功回調 if(resp.result){ // 當resp中result爲true時的操做 // 每每這個時候要操做處理resp中的data對象信息 } else{ // 當result爲false時的操做,這時每每會根據resp中的另外一屬性msg來判斷具體處理 } }).fail(function(err) { // 失敗回調 });
問題有二:url
第一,我每一個ajax中都須要寫一個一樣的相對固定的邏輯判斷(每一個公司或者項目組可能會有不一樣,可是就項目自己而言,或者放大了到公司來講必然是固定的),我以爲很煩。spa
第二,若是我只想專一處理數據,好比在成功回調裏,我直接拿到要處理要渲染的數據,在失敗的回調裏我直接拿到錯誤的代碼,有沒有這樣的可能作進一步的封裝。code
其實這倆問題是一個,總結一句話,就是不想寫那麼多if,else。有一句話我以爲說得很好,邏輯是守恆的,但若是是可預見的邏輯,是有精簡的可能的,咱們這種顯然屬於可預見的邏輯。對象
二次封裝利用了延遲對象的then方法,具體看代碼:blog
function handleAjax(url, param, type) { return ajax(url, param, type).then(function(resp){ // 成功回調 if(resp.result){ return resp.data; // 直接返回要處理的數據,做爲默認參數傳入以後done()方法的回調 } else{ return $.Deferred().reject(resp.msg); // 返回一個失敗狀態的deferred對象,把錯誤代碼做爲默認參數傳入以後fail()方法的回調 } }, function(err){ // 失敗回調 console.log(err.status); // 打印狀態碼 }); } handleAjax('www.baidu.com/getInfo').done(function(resp){ // 當result爲true的回調 }).fail(function(err){ // 當result爲false的回調 });
這就把以前很雜揉的代碼進一步的的簡化,也方便了維護,好比某一天跟你說result再也不是布爾值了,直接改爲狀態碼這樣的東西了,若是按之前一個ajax寫一個判斷,簡直要瘋。