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