成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

jquery ajax 方法封裝說(shuō)明

z2xy / 3051人閱讀

摘要:簡(jiǎn)要說(shuō)明前面我寫了一篇方法封裝及文件設(shè)計(jì)文檔,主要用來(lái)說(shuō)明我們?cè)陧?xiàng)目中通常會(huì)對(duì)的方法進(jìn)行進(jìn)一步的封裝處理,便于我們?cè)跇I(yè)務(wù)代碼中使用。這篇文檔我們主要對(duì)封裝的方法進(jìn)行一個(gè)簡(jiǎn)要說(shuō)明。

簡(jiǎn)要說(shuō)明

前面我寫了一篇《jquery ajax 方法封裝及 api 文件設(shè)計(jì)》文檔,主要用來(lái)說(shuō)明我們?cè)陧?xiàng)目中通常會(huì)對(duì) jquery 的 ajax 方法進(jìn)行進(jìn)一步的封裝處理,便于我們?cè)跇I(yè)務(wù)代碼中使用。從那篇文檔中我們可以了解到如何封裝ajax方法、如何設(shè)計(jì) API 文件,以及如何在業(yè)務(wù)代碼中調(diào)用 API 接口。

這篇文檔我們主要對(duì)封裝的 ajax 方法進(jìn)行一個(gè)簡(jiǎn)要說(shuō)明。這里的封裝主要是將 $.ajax() 返回的 jqXHR 對(duì)象,通過(guò)調(diào)用 jQuery.Deferred() 方法創(chuàng)建成一個(gè)可鏈?zhǔn)秸{(diào)用的工具對(duì)象(其實(shí) jqXHR 本身就是 Deferred 對(duì)象,本來(lái)就可以進(jìn)行鏈?zhǔn)秸{(diào)用,后面會(huì)對(duì)此進(jìn)行說(shuō)明)。這樣我們就可以使用下面這種形式進(jìn)行鏈?zhǔn)秸{(diào)用:

// 鏈?zhǔn)秸{(diào)用
absService.getAbsListData(conditionObj)
  .done(function (result) {
    var data = ts.handleData(result);
    ts.render(data, columnChange);
  })
  .fail(function (err, jqXHR) {
    Util.hideLoading("#abs-all-container");
  });

同時(shí),通過(guò)一些處理,也允許調(diào)用者使用如下形式進(jìn)行調(diào)用:

// 傳入成功回調(diào)、失敗回調(diào)
absService.getAbsListData(conditionObj, function (result) {
    var data = ts.handleData(result);
    ts.render(data, columnChange);
  }, function (err, jqXHR) {
    Util.hideLoading("#abs-all-container");
  });

實(shí)際上,從 jQuery 1.5 開始,$.ajax() 返回的 jqXHR 對(duì)象就已經(jīng)實(shí)現(xiàn)了 Promise 接口, 使它擁有了 Promise 的所有屬性,方法和行為。也就是說(shuō) $.ajax() 返回的 jqXHR 對(duì)象本身就可以使用如下形式的調(diào)用:

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

既然已經(jīng)可以使用這種方式使用 jqXHR對(duì)象,那為什么不直接將 jqXHR對(duì)象返回,然后在業(yè)務(wù)代碼中直接使用 jqXHR.done()jqXHR.fail() 方法呢?為什么還要進(jìn)一步將其包裝成一個(gè)新的 Deferred 對(duì)象呢?

答:是為了在成功和失敗回調(diào)調(diào)用之前做一些統(tǒng)一的處理,比如對(duì)接口返回的數(shù)據(jù)進(jìn)行判斷、對(duì)返回的 JSON 字符串進(jìn)行解析、在請(qǐng)求失敗時(shí)輸出方法名和錯(cuò)誤信息等,我們把這些每次接口調(diào)用都會(huì)進(jìn)行的操作進(jìn)行統(tǒng)一處理,實(shí)現(xiàn)代碼復(fù)用,這樣業(yè)務(wù)代碼中就只需要關(guān)注拿到數(shù)據(jù)后的處理邏輯即可。

這些統(tǒng)一進(jìn)行的操作,我們放在 $.ajax().done()$.ajax().fail() 方法中去執(zhí)行,然后將 $.ajax() 返回的 jqXHR對(duì)象包裝成新的 Deferred 對(duì)象,這樣就可以在業(yè)務(wù)代碼中通過(guò)鏈?zhǔn)秸{(diào)用做進(jìn)一步的處理,比如刷新表格內(nèi)容、更新頁(yè)面動(dòng)態(tài)等等。

代碼解讀
/**
 * 封裝 jquery ajax 
 * 例如:
 * ajaxRequest.ajax.triggerService(
 *   "apiCommand", [命令數(shù)據(jù)] )
 *   .then(successCallback, failureCallback);
 * );
 */
var JSON2 = require("LibsDir/json2");
var URL = "../AjaxHandler.aspx?r=";

// 用來(lái)記錄每次請(qǐng)求的唯一標(biāo)識(shí), 鍵值對(duì)形式, 形如:
// var requestIdentifier = {
//   SearchABSList: "b80a3876-9bca-40d1-b2cd-0daa799591e7",
//   SetABSUserColumns: "cafe3f01-2ee2-41f0-aeca-d630429f89f4",
// };
var requestIdentifier = {};

// 唯一標(biāo)識(shí)生成方法
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;

  /**
   * 觸發(fā)請(qǐng)求, 返回包裝成 Deferred 對(duì)象的 jqXHR
   * @param    {object}    userOptions   參數(shù)對(duì)象(包含方法名、參數(shù)對(duì)象、成功回調(diào)、失敗回調(diào))
   * @param    {string}    serviceName   方法名
   * @param    {string}    requestId     請(qǐng)求的唯一標(biāo)識(shí)
   * @returns  object
   */
  ajaxRequest.ajax = function (userOptions, serviceName, requestId) {
    userOptions = userOptions || {};

    // 將參數(shù)對(duì)象與ajax的默認(rèn)項(xiàng)組成一個(gè)新的對(duì)象, 作為 jquery ajax 方法的配置項(xiàng)
    var options = $.extend({}, ajaxRequest.ajax.defaultOpts, userOptions);

    // 將 jquery ajax 方法默認(rèn)的 success 回調(diào)和 error 回調(diào)置為 undefined
    // .done()方法取代了的過(guò)時(shí)的jqXHR.success()方法
    // .fail()方法取代了的過(guò)時(shí)的.error()方法
    options.success = undefined;
    options.error = undefined;

    // 將 jqXHR 包裝成新的 Deferred 對(duì)象返回
    // jQuery.Deferred([beforeStart]) 一個(gè)工廠函數(shù), 這個(gè)函數(shù)返回一個(gè)鏈?zhǔn)綄?shí)用對(duì)象
    // beforeStart - 一個(gè)構(gòu)造函數(shù)返回之前調(diào)用的函數(shù)
    return $.Deferred(function ($dfd) {
      $.ajax(options)
        .done(function (result, textStatus, jqXHR) {
          if (requestId === requestIdentifier[serviceName]) {
            // 比對(duì)請(qǐng)求id, 保證返回結(jié)果的正確性 (重復(fù)請(qǐng)求有可能會(huì)帶來(lái)返回結(jié)果不可靠的問(wèn)題)
            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() 的默認(rèn)設(shè)置
    defaultOpts: {
      // url: "../AjaxSecureHandler.aspx,
      dataType: "json",
      type: "POST",
      contentType: "application/x-www-form-urlencoded; charset=UTF-8"
    },

    // 在業(yè)務(wù)代碼的回調(diào)執(zhí)行之前, 做一些統(tǒng)一處理, 實(shí)現(xiàn)代碼復(fù)用
    // $dfd.resolve() 和 $dfd.reject() 的執(zhí)行, 會(huì)使得使用 .then()/.done() 中的回調(diào)方法得到執(zhí)行
    // userOptions.success() 和 userOptions.error() 是調(diào)用用戶以參數(shù)形式傳入的成功回調(diào)函數(shù)和失敗回調(diào)函數(shù)
    // 一般來(lái)說(shuō), 上述兩種方式只會(huì)有一個(gè)真正起到作用, 這取決于用戶調(diào)用的方式: 
    // 如果是使用 $.ajax().done().fail() 這種方式調(diào)用, 那么 $dfd.resolve()/$dfd.reject() 會(huì)起到作用
    // 此時(shí) userOptions.success/userOptions.error 都是 undefined, 自然不會(huì)得到執(zhí)行, 反之亦然
    handleResponse: function (result, $dfd, jqXHR, userOptions, serviceName, requestId) {
      if (!result) {
        $dfd && $dfd.reject(jqXHR, "error response format!");
        userOptions.error(jqXHR, "error response format!");
        return;
      }

      // 服務(wù)器已經(jīng)錯(cuò)誤
      if (result.ErrorCode != "200") {
        $dfd && $dfd.reject(jqXHR, result.ErrorMessage);
        userOptions.error(jqXHR, result);
        return;
      }

      if (result.Data) {
        // 將大于2^53的數(shù)字(16位以上)包裹雙引號(hào), 避免溢出
        var jsonStr = result.Data.replace(/(:s*)(d{16,})(s*,|s*})/g, "$1"$2"$3");
        var resultData = ajaxRequest.json.parse(jsonStr);

        // $dfd.resolve() 執(zhí)行之后, 業(yè)務(wù)代碼中的回調(diào)會(huì)執(zhí)行, 即.then()/.done()方法會(huì)得到執(zhí)行
        $dfd.resolve(resultData);
        // 如果是使用傳統(tǒng)的傳入成功回調(diào)函數(shù)的形式進(jìn)行調(diào)用的, 那么在此處調(diào)用用戶設(shè)定的成功回調(diào)
        userOptions.success && userOptions.success(resultData);
      } else {
        $dfd.resolve();
        userOptions.success && userOptions.success();
      }
    },

    /**
     * 構(gòu)建請(qǐng)求參數(shù)對(duì)象
     * @param    {string}    serviceName   方法名
     * @param    {object}    input         傳入的參數(shù)對(duì)象
     * @param    {function}  userSuccess   成功回調(diào)
     * @param    {function}  userError     失敗回調(diào)
     * @param    {object}    ajaxParams    其他參數(shù)
     * @returns  object
     */
    buildServiceRequest: function (serviceName, input, userSuccess, userError, ajaxParams) {
      // 這里是根據(jù)后臺(tái)要求構(gòu)建的
      var requestData = {
        MethodAlias: serviceName, // 方法名
        Parameter: input // 傳遞的參數(shù)
      };

      var request = $.extend({}, ajaxParams, {
        // 這里要對(duì)傳遞的 JSON 字符串參數(shù)數(shù)據(jù)使用 escape 方法進(jìn)行編碼
        // "data=" 是根據(jù)項(xiàng)目約定增加的,與 contentType 相對(duì)應(yīng)
        data: "data=" + escape(ajaxRequest.json.stringify(requestData)),
        success: userSuccess,
        error: function (jqXHR, textStatus, errorThrown) {
          // 這里是在請(qǐng)求出錯(cuò)的時(shí)候做一個(gè)統(tǒng)一處理, 輸出方法名和錯(cuò)誤對(duì)象
          console.log(serviceName, jqXHR);
          if (userError && (typeof userError === "function")) {
            userError(jqXHR, textStatus, errorThrown);
          }
        }
      });

      return request;
    },

    // 構(gòu)建參數(shù)對(duì)象, 生成唯一標(biāo)識(shí), 觸發(fā)請(qǐng)求
    triggerService: function (serviceName, input, success, error, ajaxParams) {
      // 構(gòu)建參數(shù)對(duì)象
      var request = ajaxRequest.ajax.buildServiceRequest(serviceName, input, success, error, ajaxParams);

      // 生成此次 ajax 請(qǐng)求唯一標(biāo)識(shí)
      var requestId = requestIdentifier[serviceName] = generateGUID();
      request.url = URL + requestId;

      // 觸發(fā)請(qǐng)求
      return ajaxRequest.ajax(request, serviceName, requestId);
    }
  });

})(jQuery);

module.exports = ajaxRequest;

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/103025.html

相關(guān)文章

  • Ajax設(shè)置請(qǐng)求和接收響應(yīng)、自己封裝簡(jiǎn)易jQuery.Ajax、回調(diào)函數(shù)

    摘要:設(shè)置請(qǐng)求和接收響應(yīng)自己封裝簡(jiǎn)易這篇文章是承接前幾篇博客的是前幾篇繼續(xù)學(xué)習(xí)包括學(xué)習(xí)與理解和簡(jiǎn)化版自己實(shí)現(xiàn)等這篇文章只算是我的個(gè)人學(xué)習(xí)筆記內(nèi)容沒(méi)有精心排版一些錯(cuò)誤請(qǐng)見(jiàn)諒所有代碼都在這里從歷史可以看到所有代碼擺闊一個(gè)簡(jiǎn)易的服務(wù)器所有代碼在歷史里 Ajax設(shè)置請(qǐng)求和接收響應(yīng)、自己封裝簡(jiǎn)易jQuery.Ajax 這篇文章是承接前幾篇博客的,是前幾篇繼續(xù)學(xué)習(xí)包括Ajax學(xué)習(xí)與理解和簡(jiǎn)化版自己實(shí)現(xiàn)j...

    Harpsichord1207 評(píng)論0 收藏0
  • 前后分離模型之封裝 Api 調(diào)用

    摘要:和異步處理調(diào)用訪問(wèn)數(shù)據(jù)采用的方式,這是一個(gè)異步過(guò)程,異步過(guò)程最基本的處理方式是事件或回調(diào),其實(shí)這兩種處理方式實(shí)現(xiàn)原理差不多,都需要在調(diào)用異步過(guò)程的時(shí)候傳入一個(gè)在異步過(guò)程結(jié)束的時(shí)候調(diào)用的接口。 Ajax 和異步處理 調(diào)用 API 訪問(wèn)數(shù)據(jù)采用的 Ajax 方式,這是一個(gè)異步過(guò)程,異步過(guò)程最基本的處理方式是事件或回調(diào),其實(shí)這兩種處理方式實(shí)現(xiàn)原理差不多,都需要在調(diào)用異步過(guò)程的時(shí)候傳入一個(gè)在異...

    trilever 評(píng)論0 收藏0
  • 異步 JavaScript 與 Promise

    摘要:為這些回調(diào)函數(shù)分別命名并分離存放可以在形式上減少嵌套,使代碼清晰,但仍然不能解決問(wèn)題。如果在一個(gè)結(jié)束成功或失敗,同前面的說(shuō)明后,添加針對(duì)成功或失敗的回調(diào),則回調(diào)函數(shù)會(huì)立即執(zhí)行。 異步? 我在很多地方都看到過(guò)異步(Asynchronous)這個(gè)詞,但在我還不是很理解這個(gè)概念的時(shí)候,卻發(fā)現(xiàn)自己常常會(huì)被當(dāng)做已經(jīng)很清楚(* ̄? ̄)。 如果你也有類似的情況,沒(méi)關(guān)系,搜索一下這個(gè)詞,就可以得到大致...

    livem 評(píng)論0 收藏0
  • jQuery筆記總結(jié)篇

    摘要:希望在做所有事情之前,操作文檔。不受層級(jí)限制子選擇器在給定的父元素下匹配所有子元素。相鄰選擇器匹配所有緊接在元素后的元素。判斷當(dāng)前對(duì)象中的某個(gè)元素是否包含指定類名,包含返回,不包含返回下標(biāo)過(guò)濾器精確選出指定下標(biāo)元素獲取第個(gè)元素。 原文鏈接 http://blog.poetries.top/2016... 首先,來(lái)了解一下jQuery學(xué)習(xí)的整體思路 showImg(https://seg...

    NoraXie 評(píng)論0 收藏0
  • Jquery就是這么簡(jiǎn)單

    摘要:在內(nèi)部還是調(diào)用這些方法。對(duì)象下標(biāo),從開始對(duì)象下標(biāo),從開始再次重申對(duì)象只能調(diào)用對(duì)象的,對(duì)象只能調(diào)用對(duì)象的對(duì)象轉(zhuǎn)成值得注意的是在腳本內(nèi),是代表對(duì)象的。對(duì)象轉(zhuǎn)成對(duì)象語(yǔ)法也非常簡(jiǎn)單在內(nèi)寫上對(duì)象,就變成了對(duì)象了。在文檔中對(duì)它的解釋是這樣子的。 什么是Jquery? Jquey就是一款跨主流瀏覽器的JavaScript庫(kù),簡(jiǎn)化JavaScript對(duì)HTML操作 就是封裝了JavaScript,能夠...

    wpw 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<