摘要:簡要說明前面我寫了一篇方法封裝及文件設計文檔,主要用來說明我們在項目中通常會對的方法進行進一步的封裝處理,便于我們在業務代碼中使用。這篇文檔我們主要對封裝的方法進行一個簡要說明。
簡要說明
前面我寫了一篇《jquery ajax 方法封裝及 api 文件設計》文檔,主要用來說明我們在項目中通常會對 jquery 的 ajax 方法進行進一步的封裝處理,便于我們在業務代碼中使用。從那篇文檔中我們可以了解到如何封裝ajax方法、如何設計 API 文件,以及如何在業務代碼中調用 API 接口。
這篇文檔我們主要對封裝的 ajax 方法進行一個簡要說明。這里的封裝主要是將 $.ajax() 返回的 jqXHR 對象,通過調用 jQuery.Deferred() 方法創建成一個可鏈式調用的工具對象(其實 jqXHR 本身就是 Deferred 對象,本來就可以進行鏈式調用,后面會對此進行說明)。這樣我們就可以使用下面這種形式進行鏈式調用:
// 鏈式調用 absService.getAbsListData(conditionObj) .done(function (result) { var data = ts.handleData(result); ts.render(data, columnChange); }) .fail(function (err, jqXHR) { Util.hideLoading("#abs-all-container"); });
同時,通過一些處理,也允許調用者使用如下形式進行調用:
// 傳入成功回調、失敗回調 absService.getAbsListData(conditionObj, function (result) { var data = ts.handleData(result); ts.render(data, columnChange); }, function (err, jqXHR) { Util.hideLoading("#abs-all-container"); });
實際上,從 jQuery 1.5 開始,$.ajax() 返回的 jqXHR 對象就已經實現了 Promise 接口, 使它擁有了 Promise 的所有屬性,方法和行為。也就是說 $.ajax() 返回的 jqXHR 對象本身就可以使用如下形式的調用:
$.ajax(options) .done(function (result, textStatus, jqXHR) { if (requestId === requestIdentifier[serviceName]) { ajaxRequest.ajax.handleResponse(result, $dfd, jqXHR, userOptions, serviceName, requestId); } }) .fail(function (jqXHR, textStatus, errorThrown) { if (requestId === requestIdentifier[serviceName]) { //jqXHR.status $dfd.reject.apply(this, arguments); userOptions.error.apply(this, arguments); } });
既然已經可以使用這種方式使用 jqXHR對象,那為什么不直接將 jqXHR對象返回,然后在業務代碼中直接使用 jqXHR.done() 和 jqXHR.fail() 方法呢?為什么還要進一步將其包裝成一個新的 Deferred 對象呢?
答:是為了在成功和失敗回調調用之前做一些統一的處理,比如對接口返回的數據進行判斷、對返回的 JSON 字符串進行解析、在請求失敗時輸出方法名和錯誤信息等,我們把這些每次接口調用都會進行的操作進行統一處理,實現代碼復用,這樣業務代碼中就只需要關注拿到數據后的處理邏輯即可。
這些統一進行的操作,我們放在 $.ajax().done() 和 $.ajax().fail() 方法中去執行,然后將 $.ajax() 返回的 jqXHR對象包裝成新的 Deferred 對象,這樣就可以在業務代碼中通過鏈式調用做進一步的處理,比如刷新表格內容、更新頁面動態等等。
代碼解讀/** * 封裝 jquery ajax * 例如: * ajaxRequest.ajax.triggerService( * "apiCommand", [命令數據] ) * .then(successCallback, failureCallback); * ); */ var JSON2 = require("LibsDir/json2"); var URL = "../AjaxHandler.aspx?r="; // 用來記錄每次請求的唯一標識, 鍵值對形式, 形如: // var requestIdentifier = { // SearchABSList: "b80a3876-9bca-40d1-b2cd-0daa799591e7", // SetABSUserColumns: "cafe3f01-2ee2-41f0-aeca-d630429f89f4", // }; var requestIdentifier = {}; // 唯一標識生成方法 function generateGUID() { var d = new Date().getTime(); if (typeof performance !== "undefined" && typeof performance.now === "function") { d += performance.now(); } return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) { var r = (d + Math.random() * 16) % 16 | 0; d = Math.floor(d / 16); return (c === "x" ? r : (r & 0x3 | 0x8)).toString(16); }); } // 模塊主體 var ajaxRequest = ajaxRequest || {}; (function ($) { if (!$) { throw "jquery獲取失敗!"; } ajaxRequest.json = JSON2; /** * 觸發請求, 返回包裝成 Deferred 對象的 jqXHR * @param {object} userOptions 參數對象(包含方法名、參數對象、成功回調、失敗回調) * @param {string} serviceName 方法名 * @param {string} requestId 請求的唯一標識 * @returns object */ ajaxRequest.ajax = function (userOptions, serviceName, requestId) { userOptions = userOptions || {}; // 將參數對象與ajax的默認項組成一個新的對象, 作為 jquery ajax 方法的配置項 var options = $.extend({}, ajaxRequest.ajax.defaultOpts, userOptions); // 將 jquery ajax 方法默認的 success 回調和 error 回調置為 undefined // .done()方法取代了的過時的jqXHR.success()方法 // .fail()方法取代了的過時的.error()方法 options.success = undefined; options.error = undefined; // 將 jqXHR 包裝成新的 Deferred 對象返回 // jQuery.Deferred([beforeStart]) 一個工廠函數, 這個函數返回一個鏈式實用對象 // beforeStart - 一個構造函數返回之前調用的函數 return $.Deferred(function ($dfd) { $.ajax(options) .done(function (result, textStatus, jqXHR) { if (requestId === requestIdentifier[serviceName]) { // 比對請求id, 保證返回結果的正確性 (重復請求有可能會帶來返回結果不可靠的問題) ajaxRequest.ajax.handleResponse(result, $dfd, jqXHR, userOptions, serviceName, requestId); } }) .fail(function (jqXHR, textStatus, errorThrown) { if (requestId === requestIdentifier[serviceName]) { // jqXHR.status $dfd.reject.apply(this, arguments); userOptions.error.apply(this, arguments); } }); }); }; $.extend(ajaxRequest.ajax, { // $.ajax() 的默認設置 defaultOpts: { // url: "../AjaxSecureHandler.aspx, dataType: "json", type: "POST", contentType: "application/x-www-form-urlencoded; charset=UTF-8" }, // 在業務代碼的回調執行之前, 做一些統一處理, 實現代碼復用 // $dfd.resolve() 和 $dfd.reject() 的執行, 會使得使用 .then()/.done() 中的回調方法得到執行 // userOptions.success() 和 userOptions.error() 是調用用戶以參數形式傳入的成功回調函數和失敗回調函數 // 一般來說, 上述兩種方式只會有一個真正起到作用, 這取決于用戶調用的方式: // 如果是使用 $.ajax().done().fail() 這種方式調用, 那么 $dfd.resolve()/$dfd.reject() 會起到作用 // 此時 userOptions.success/userOptions.error 都是 undefined, 自然不會得到執行, 反之亦然 handleResponse: function (result, $dfd, jqXHR, userOptions, serviceName, requestId) { if (!result) { $dfd && $dfd.reject(jqXHR, "error response format!"); userOptions.error(jqXHR, "error response format!"); return; } // 服務器已經錯誤 if (result.ErrorCode != "200") { $dfd && $dfd.reject(jqXHR, result.ErrorMessage); userOptions.error(jqXHR, result); return; } if (result.Data) { // 將大于2^53的數字(16位以上)包裹雙引號, 避免溢出 var jsonStr = result.Data.replace(/(:s*)(d{16,})(s*,|s*})/g, "$1"$2"$3"); var resultData = ajaxRequest.json.parse(jsonStr); // $dfd.resolve() 執行之后, 業務代碼中的回調會執行, 即.then()/.done()方法會得到執行 $dfd.resolve(resultData); // 如果是使用傳統的傳入成功回調函數的形式進行調用的, 那么在此處調用用戶設定的成功回調 userOptions.success && userOptions.success(resultData); } else { $dfd.resolve(); userOptions.success && userOptions.success(); } }, /** * 構建請求參數對象 * @param {string} serviceName 方法名 * @param {object} input 傳入的參數對象 * @param {function} userSuccess 成功回調 * @param {function} userError 失敗回調 * @param {object} ajaxParams 其他參數 * @returns object */ buildServiceRequest: function (serviceName, input, userSuccess, userError, ajaxParams) { // 這里是根據后臺要求構建的 var requestData = { MethodAlias: serviceName, // 方法名 Parameter: input // 傳遞的參數 }; var request = $.extend({}, ajaxParams, { // 這里要對傳遞的 JSON 字符串參數數據使用 escape 方法進行編碼 // "data=" 是根據項目約定增加的,與 contentType 相對應 data: "data=" + escape(ajaxRequest.json.stringify(requestData)), success: userSuccess, error: function (jqXHR, textStatus, errorThrown) { // 這里是在請求出錯的時候做一個統一處理, 輸出方法名和錯誤對象 console.log(serviceName, jqXHR); if (userError && (typeof userError === "function")) { userError(jqXHR, textStatus, errorThrown); } } }); return request; }, // 構建參數對象, 生成唯一標識, 觸發請求 triggerService: function (serviceName, input, success, error, ajaxParams) { // 構建參數對象 var request = ajaxRequest.ajax.buildServiceRequest(serviceName, input, success, error, ajaxParams); // 生成此次 ajax 請求唯一標識 var requestId = requestIdentifier[serviceName] = generateGUID(); request.url = URL + requestId; // 觸發請求 return ajaxRequest.ajax(request, serviceName, requestId); } }); })(jQuery); module.exports = ajaxRequest;
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/103025.html
摘要:設置請求和接收響應自己封裝簡易這篇文章是承接前幾篇博客的是前幾篇繼續學習包括學習與理解和簡化版自己實現等這篇文章只算是我的個人學習筆記內容沒有精心排版一些錯誤請見諒所有代碼都在這里從歷史可以看到所有代碼擺闊一個簡易的服務器所有代碼在歷史里 Ajax設置請求和接收響應、自己封裝簡易jQuery.Ajax 這篇文章是承接前幾篇博客的,是前幾篇繼續學習包括Ajax學習與理解和簡化版自己實現j...
摘要:和異步處理調用訪問數據采用的方式,這是一個異步過程,異步過程最基本的處理方式是事件或回調,其實這兩種處理方式實現原理差不多,都需要在調用異步過程的時候傳入一個在異步過程結束的時候調用的接口。 Ajax 和異步處理 調用 API 訪問數據采用的 Ajax 方式,這是一個異步過程,異步過程最基本的處理方式是事件或回調,其實這兩種處理方式實現原理差不多,都需要在調用異步過程的時候傳入一個在異...
摘要:為這些回調函數分別命名并分離存放可以在形式上減少嵌套,使代碼清晰,但仍然不能解決問題。如果在一個結束成功或失敗,同前面的說明后,添加針對成功或失敗的回調,則回調函數會立即執行。 異步? 我在很多地方都看到過異步(Asynchronous)這個詞,但在我還不是很理解這個概念的時候,卻發現自己常常會被當做已經很清楚(* ̄? ̄)。 如果你也有類似的情況,沒關系,搜索一下這個詞,就可以得到大致...
摘要:希望在做所有事情之前,操作文檔。不受層級限制子選擇器在給定的父元素下匹配所有子元素。相鄰選擇器匹配所有緊接在元素后的元素。判斷當前對象中的某個元素是否包含指定類名,包含返回,不包含返回下標過濾器精確選出指定下標元素獲取第個元素。 原文鏈接 http://blog.poetries.top/2016... 首先,來了解一下jQuery學習的整體思路 showImg(https://seg...
摘要:在內部還是調用這些方法。對象下標,從開始對象下標,從開始再次重申對象只能調用對象的,對象只能調用對象的對象轉成值得注意的是在腳本內,是代表對象的。對象轉成對象語法也非常簡單在內寫上對象,就變成了對象了。在文檔中對它的解釋是這樣子的。 什么是Jquery? Jquey就是一款跨主流瀏覽器的JavaScript庫,簡化JavaScript對HTML操作 就是封裝了JavaScript,能夠...
閱讀 3675·2021-11-16 11:41
閱讀 2880·2021-09-23 11:45
閱讀 687·2019-08-30 15:44
閱讀 538·2019-08-30 13:10
閱讀 1961·2019-08-30 12:49
閱讀 3526·2019-08-28 17:51
閱讀 1471·2019-08-26 12:20
閱讀 698·2019-08-23 17:56