搗鼓一個Ajax請求管理器

     隨着前端技術的不斷髮展,如今作的項目裏不少頁面裏都會有大量的ajax請求,隨之而來就有了一些問題:前端

    1.不必的ajax請求怎麼處理?ajax

    2.ajax鏈式調用怎麼維護?app

  ajax鏈式調用最原始的寫法:函數

    

$.ajax({
    ...,
    success:function(data){
        $.ajax(...);
    }
})    

 

     這裏ajax鏈式調用咱們固然能夠使用Jquery的Queue或者When...Then(Done)實現,可是大量的ajax鏈式調用,這樣寫也會致使代碼過於複雜。this

     Jquery裏用Queue實現的ajax鏈式調用:spa

  

$.queue("myAjaxQueue",[
    function(){
          $.ajax({
               ...,
               success:function(data){
                   //do something
                   $.dequeue("myAjaxQueue");
               }
          })
    },
    function(){
          $.ajax({
               ...,
               success:function(data){
                   //do something
                   $.dequeue("myAjaxQueue");
               }
          })
    }
]);     
$.dequeue("myAjaxQueue")

When...Then(Done)實現的鏈式調用:prototype

$.when($.ajax({
                ...
            }), $.ajax({
                ...
            })).done(function (xhr1, xhr2) {
                //do something
            });

爲了解放本身的雙手,少寫幾行代碼,因而決定本身寫一個Ajax隊列管理器,這裏第一個遇到的問題是,怎麼讓後面的ajax請求知道何時輪到他們執行,顯然我必須在ajax回調裏發出通知,這裏我用了函數劫持來動態添加發出通知的代碼:首先定義一個函數劫持的封裝函數:code

/// <summary>通用的函數劫持定義</summary>
    /// <param name="obj" type="Object">被劫持的對象</param>
    /// <param name="method" type="String">被劫持的方法名</param>
    /// <param name="hookLogic" type="Function">劫持邏輯</param>
    /// <param name="beforeMethod" type="Boolean">是否在原函數邏輯執行以前執行</param>
    hookMethod = function (obj, method, hookLogic, beforeMethod) {
        var _method = obj[method];
        if (!!_method) {
            obj[method] = function () {
                if (beforeMethod) {
                    hookLogic.apply(this, arguments);
                    _method.apply(this, arguments);
                } else {
                    _method.apply(this, arguments);
                    hookLogic.apply(this, arguments);
                }
            }
        }
    };

而後Ajax隊列管理器算是有着落了:對象

    AjaxQueue = function (name) {
        /// <summary>Ajax隊列管理器</summary>
        /// <param name="name" type="String">隊列名稱</param>
        this._name = name;
        this._requests = [{}];
        $(document).queue(this._name, []);
    }

    AjaxQueue.prototype = {
        Request: function (key, xhrOption) {
            /// <summary>將Ajax請求放入隊列</summary>
            /// <param name="key" type="String">Ajax請求標示,用於管理Ajax狀態</param>
            /// <param name="xhrOption" type="Object Literal">JQuery Ajax對象參數選項</param>
            var self = this;
            if (!!xhrOption.complete) {
                utils.hookMethod(xhrOption, "complete", ajaxHook, false);
            } else {
                utils.hookMethod(xhrOption, "success", ajaxHook, false);
                utils.hookMethod(xhrOption, "error", ajaxHook, false);
            };

            function ajaxHook() {
                $(document).dequeue(self._name);

            }

            $(document).queue(self._name, function () {
                self.Abort(key);//取消未完成的相同請求
           xhr = $.ajax(xhrOption);
                self._requests.push({
                    key: key,
                    xhr: xhr
                });
            });

            return self;
        },
        Abort: function (key) {
            var self = this;
            $.each(self._requests || [], function (i, req) {
                if (req.key === key) {
                    try {
                        req.xhr.abort();
                    }
                    catch (err) {

                    }
                }
            });
        },
        Run: function () {
            $(document).dequeue(this._name);
            return this;
        }
    };

裏面集成了ajax鏈式調用、取消多餘Ajax請求之功能,本文有任何不足之處,還望各位大蝦指教。blog

相關文章
相關標籤/搜索