隨着前端技術的不斷髮展,如今作的項目裏不少頁面裏都會有大量的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