摘要:前言在中大型的前端應用里面項目里面通常包夾了大量的請求,通常情況這些請求夾雜在業務代碼里面拓展維護的成本比較大。測試代碼及源碼下載在中歸納本篇文章是通過對請求調用前,調用后的統一處理來更有效的控制這些請求類似于面向切面的思想。
前言
在中大型的前端應用里面項目里面通常包夾了大量的ajax請求,通常情況這些請求夾雜在業務代碼里面,拓展維護的成本比較大。
如要改整個項目的url前綴(后端把接口路徑統一加個assets或者http換成https),或者要改請求的類型get換post,亦或者統一加個CSRFToken,我們該當如何,手動一個個把自己一頭扎進業務代碼里面去修改嗎?
此時不妨試試用一個js去統一管理這些ajax請求。
分析以下是我們使用ajax請求的方式
調用請求的時候拼裝url,在較多ajax請求的時候面,維護拓展就變得非常的艱難
本文章想法是把url抽象成不同類型的參數
公共型參數: 每個url都共用的部分 如http類型,url前綴,mockurl前綴,token等
配置型參數: 每個url都不一樣的,但可以提前預知的部分,如uri地址,ajax請求方式(get/post)
業務型參數: 具體進業務場景方能算出來的參數 如test=xxx(xxx的值只有程序運行的時候才知道值)
公共型參數和配置型參數可以在項目初始化的時候通過邏輯控制并存起來,
業務型參數在具體調用的時候在具體的業務場景獲取。
在通過統一的ajax請求獲取資源
統一的ajax請求,可以在失敗之后,統一拋出異常,成功之后統一改變獲取數據的結構等等好處
代碼實現 簡單工廠存儲url參數對象簡單工程創建 參數實例,并將實例對象存儲在context內部
(function (root,$) { //簡單工廠生成項目統一的ajax參數對象 var DBFactory = { __: {}, //可有業務代碼設置mockUrl,prefixUrl等 set: function (key, value) { this.__[key] = value; }, get: function (key) { return this.__[key]; }, create: function (name, methods) { // 禁止創建重名的DB實例 if (this.context[name]) { console.warn("DB: "" + name + "" is existed! "); return; } return this.context[name] = new DB(name, methods); }, // 存儲db實例 context: { } }; //DB構造函數 負責構造ajax參數對象 function DB(DBName, methods) { var t = this; t.cache = {}; $.each(methods, function (method, config) { if (typeof config === "function") { t[method] = config; return; } t[method] = function (query) { var cfg = {}; cfg.method = method; cfg.DBName = DBName; cfg.mockUrl = config.mockUrl; // 如果設置了`mock`代理 if (cfg.mockUrl && typeof DBFactory.__.mockProxy === "function") { cfg.mockUrl = DBFactory.__.mockProxy(cfg.mockUrl); } //合并參數 cfg.query = $.extend({}, config.query || {}, query || {}); //判斷是否mock cfg.isMock = config.url ? false : true; //url前綴供getUrl計算url t.urlPrefix = DBFactory.get("urlPrefix") || ""; //url cfg.url = cfg.isMock ? cfg.mockUrl : (t.getUrl(config.url) || cfg.mockUrl); // 是否是全局只獲取一次 cfg.once = typeof config.once === "boolean" ? config.once : false; // 數據緩存,如果`once`設置為true,則在第二次請求的時候直接返回改緩存數據。 t.cache[method] = t.cache[method] || null; cfg.jsonp = config.jsonp || false; cfg.type = config.type || "POST"; return request(cfg, t); }; }); } /** * 獲取正式接口的完整`url` * 如果通過`DB.set("urlPrefix", "https://xxx")`設置了全局`url`的前綴,則執行補全 */ DB.prototype.getUrl=function (url) { if (this.urlPrefix && url.indexOf("http") !== 0 && url.indexOf("http://") !== 0) { return this.urlPrefix + url; } else { return url; } }; /** * * @param cfg 屬性對象提供給ajax修改請求屬性 * @param db db提供緩存 * @returns ajax promise */ function request(cfg, db) { var defer = $.Deferred(); if (cfg.once && db.cache[cfg.method]) { defer.resolve(db.cache[cfg.method]); } else { var ajaxOptions = { url: cfg.url, data: cfg.query, success: function (resp) { //cfg.once && (db.cache[cfg.method] = resp); defer.resolve(resp); }, error: function (error) { defer.reject({ fail:true, msg: error }); } }; if (cfg.jsonp === true) { ajaxOptions.dataType = "jsonp"; } else { ajaxOptions.dataType = "json"; ajaxOptions.type = cfg.type; } $.ajax(ajaxOptions); } return defer.promise(); }; root.DBFactory = DBFactory; })(this,$);配置參數
db.js 負責注冊ajax請求,并全局的設置url前綴,是否啟用mockurl,對不同請求配置不同的請求方式,是否jsonp等
(function (DBF) { var isOnline = false; // 設置全局的`url`前綴 var urlPrefixForLocal = location.protocol + "http://" + location.host+"/"; if (!isOnline) { DBF.set("urlPrefix", urlPrefixForLocal); } else { DBF.set("urlPrefix", "/trs"); } // MockProxy mock 數據服務器(node/php代理)代理,以跨過同源檢測 DBF.set("mockProxy", function (mockUrl) { return "/mock?url=" + mockUrl }); DBF.create("Test", { get: { type: "GET", // jsonp: true, url: "example/ajax-data/data.json" // mockUrl: urlPrefixForLocal + "/ajax-data/data.json", //once: true } }); DBF.create("GetPersonInfo", { get: { type: "GET", url: "getMySimpleInfo.json", once: true } }); window.DB = DBF.context; })(window.DBFactory);開始測試 加上請求的資源 調用代碼
ajax的真正調用者,通過DB.xxx 拿到參數對象后以get的形式觸發實際的ajax請求,并附帶業務代碼里面的參數。
$(document).ready( function () { var DB = window.DB; var promise1 = $.when(DB.Test.get({test: true})); var promise2 = $.when(DB.GetPersonInfo.get()); promise1.then( function (res) { console.log(res) $("#promise1").html("promise1:"+res.data); }, function (error) { console.log(error); }); promise2.then( function (res) { console.log(res) }, function (error) { $("#promise2").html("promise2:"+error.msg.responseText); }); } )運行結果
promise1 拿data.json 返回成功
promise2 拿getMySimpleInfo.json 資源未獲取到,返回失敗
本篇文章是以jquery形式展示的,但稍事修改也是可以在backbone,react等框架內使用。
測試代碼及源碼下載在https://github.com/laughing-p... 中
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/80041.html
摘要:作者滬江前端開發工程師本文原創翻譯,有不當的地方歡迎指出。管理數據,而提供服務器上的數據,因此應用于處理網絡請求。結論使用建立的應用都是模塊化的會成為其中一個模塊,庫是另一個模塊。原文原創新書移動前端高效開發實戰已在亞馬遜京東當當開售。 作者:Oral (滬江Web前端開發工程師)本文原創翻譯,有不當的地方歡迎指出。轉載請指明出處。 當你問起有關AJAX與React時,老司機們首先就會...
摘要:進過下面的步驟,一步一步的配置,就可以讓你正確的在項目中引入微信的。在進行了正確的微信文件引入后看上面在頁面中調用如下代碼就可以注入權限驗證配置。可以通過微信提供的兩個接口來進行事件回調。到這為止,微信的接入就完成了。 微信JS-SDK的功能 如果你點進來,那么我相信你應該知道微信的JS-SDK可以用來做什么了。微信的官方文檔描述如下。 微信JS-SDK是微信公眾平臺面向網頁開發者提供...
摘要:更好的異步編程上面的方法可以適用于那些比較簡單的異步工作流程。小結的組合目前是最強大,也是最優雅的異步流程管理編程方式。 訪問原文地址 generators主要作用就是提供了一種,單線程的,很像同步方法的編程風格,方便你把異步實現的那些細節藏在別處。這讓我們可以用一種很自然的方式書寫我們代碼中的流程和狀態邏輯,不再需要去遵循那些奇怪的異步編程風格。 換句話說,通過將我們generato...
摘要:起初,項目使用的是,其提供的方法用著比較爽,由于項目的很多數據來自豆瓣的,直接上簡單方便,跨域什么的不考慮。跨域問題,上面已經介紹,在不能操控的豆瓣數據上,使用的是。 項目地址 在線演示 不識廬山真面目,只緣身在此山中。 大概一個月前,開源了Vue重構豆瓣移動端的項目,效果還可以,收到了很多小伙伴的反饋,話說是要寫一些文章的,但遲遲沒有動筆,估計小伙伴們等的花都謝了,拖延癥是病,需要治...
摘要:管理后臺,日常就是提交各種表單了,這部分現有的方案,比如表單提交或者收集信息提交。,可以用于前端開發的工程構建。帶了人的前端團隊,你的精力開始在配合公司其他部門做用戶數據增長了。開始考慮使用的。? ? ? ?hi,大家伙,我是佛系大大,很高興與你們一起溝通,學習,進步。 ? ? ? ?很久不更新博客了,現在回來再寫博客,盡然是有些懷念的感覺,幸福的感覺。因為寫博客,內心會很寧靜,沉浸在自己的...
閱讀 903·2021-11-22 13:53
閱讀 2533·2021-10-15 09:40
閱讀 1001·2021-10-14 09:42
閱讀 3475·2021-09-22 15:59
閱讀 888·2021-09-02 09:47
閱讀 2368·2019-08-30 15:54
閱讀 1438·2019-08-29 17:14
閱讀 400·2019-08-29 15:15