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

資訊專欄INFORMATION COLUMN

如何更有效的在中大型項目中管理ajax請求

ACb0y / 2280人閱讀

摘要:前言在中大型的前端應(yīng)用里面項目里面通常包夾了大量的請求,通常情況這些請求夾雜在業(yè)務(wù)代碼里面拓展維護(hù)的成本比較大。測試代碼及源碼下載在中歸納本篇文章是通過對請求調(diào)用前,調(diào)用后的統(tǒng)一處理來更有效的控制這些請求類似于面向切面的思想。

前言

在中大型的前端應(yīng)用里面項目里面通常包夾了大量的ajax請求,通常情況這些請求夾雜在業(yè)務(wù)代碼里面,拓展維護(hù)的成本比較大。

如要改整個項目的url前綴(后端把接口路徑統(tǒng)一加個assets或者h(yuǎn)ttp換成https),或者要改請求的類型get換post,亦或者統(tǒng)一加個CSRFToken,我們該當(dāng)如何,手動一個個把自己一頭扎進(jìn)業(yè)務(wù)代碼里面去修改嗎?

此時不妨試試用一個js去統(tǒng)一管理這些ajax請求。

分析

以下是我們使用ajax請求的方式

調(diào)用請求的時候拼裝url,在較多ajax請求的時候面,維護(hù)拓展就變得非常的艱難
本文章想法是把url抽象成不同類型的參數(shù)

將url分為三類:

公共型參數(shù): 每個url都共用的部分 如http類型,url前綴,mockurl前綴,token等

配置型參數(shù): 每個url都不一樣的,但可以提前預(yù)知的部分,如uri地址,ajax請求方式(get/post)

業(yè)務(wù)型參數(shù): 具體進(jìn)業(yè)務(wù)場景方能算出來的參數(shù) 如test=xxx(xxx的值只有程序運行的時候才知道值)

公共型參數(shù)和配置型參數(shù)可以在項目初始化的時候通過邏輯控制并存起來,
業(yè)務(wù)型參數(shù)在具體調(diào)用的時候在具體的業(yè)務(wù)場景獲取。
在通過統(tǒng)一的ajax請求獲取資源

流程圖

統(tǒng)一的ajax請求,可以在失敗之后,統(tǒng)一拋出異常,成功之后統(tǒng)一改變獲取數(shù)據(jù)的結(jié)構(gòu)等等好處

代碼實現(xiàn) 簡單工廠存儲url參數(shù)對象

簡單工程創(chuàng)建 參數(shù)實例,并將實例對象存儲在context內(nèi)部

    (function (root,$) {
    //簡單工廠生成項目統(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實例
            if (this.context[name]) {
                console.warn("DB: "" + name + "" is existed! ");
                return;
            }
            return this.context[name] = new DB(name, methods);
        },
        // 存儲db實例
        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計算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ù)據(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í)行補全
     */
    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ā)實際的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);
                        });
            }
    )
   
運行結(jié)果

promise1 拿data.json 返回成功
promise2 拿getMySimpleInfo.json 資源未獲取到,返回失敗

本篇文章是以jquery形式展示的,但稍事修改也是可以在backbone,react等框架內(nèi)使用。
測試代碼及源碼下載在https://github.com/laughing-p... 中

歸納 本篇文章是通過對ajax請求調(diào)用前,調(diào)用后的統(tǒng)一處理來更有效的控制這些請求,類似于面向切面的思想。

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

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

相關(guān)文章

  • 翻譯 | React AJAX最佳實踐

    摘要:作者滬江前端開發(fā)工程師本文原創(chuàng)翻譯,有不當(dāng)?shù)牡胤綒g迎指出。管理數(shù)據(jù),而提供服務(wù)器上的數(shù)據(jù),因此應(yīng)用于處理網(wǎng)絡(luò)請求。結(jié)論使用建立的應(yīng)用都是模塊化的會成為其中一個模塊,庫是另一個模塊。原文原創(chuàng)新書移動前端高效開發(fā)實戰(zhàn)已在亞馬遜京東當(dāng)當(dāng)開售。 作者:Oral (滬江Web前端開發(fā)工程師)本文原創(chuàng)翻譯,有不當(dāng)?shù)牡胤綒g迎指出。轉(zhuǎn)載請指明出處。 當(dāng)你問起有關(guān)AJAX與React時,老司機們首先就會...

    DirtyMind 評論0 收藏0
  • 如何正確的在項目接入微信JS-SDK

    摘要:進(jìn)過下面的步驟,一步一步的配置,就可以讓你正確的在項目中引入微信的。在進(jìn)行了正確的微信文件引入后看上面在頁面中調(diào)用如下代碼就可以注入權(quán)限驗證配置??梢酝ㄟ^微信提供的兩個接口來進(jìn)行事件回調(diào)。到這為止,微信的接入就完成了。 微信JS-SDK的功能 如果你點進(jìn)來,那么我相信你應(yīng)該知道微信的JS-SDK可以用來做什么了。微信的官方文檔描述如下。 微信JS-SDK是微信公眾平臺面向網(wǎng)頁開發(fā)者提供...

    ivyzhang 評論0 收藏0
  • ES6的異步編程:Generators函數(shù)+Promise:最強大的異步處理方式

    摘要:更好的異步編程上面的方法可以適用于那些比較簡單的異步工作流程。小結(jié)的組合目前是最強大,也是最優(yōu)雅的異步流程管理編程方式。 訪問原文地址 generators主要作用就是提供了一種,單線程的,很像同步方法的編程風(fēng)格,方便你把異步實現(xiàn)的那些細(xì)節(jié)藏在別處。這讓我們可以用一種很自然的方式書寫我們代碼中的流程和狀態(tài)邏輯,不再需要去遵循那些奇怪的異步編程風(fēng)格。 換句話說,通過將我們generato...

    Taonce 評論0 收藏0
  • 雜篇 - Vue豆瓣系列文章

    摘要:起初,項目使用的是,其提供的方法用著比較爽,由于項目的很多數(shù)據(jù)來自豆瓣的,直接上簡單方便,跨域什么的不考慮??缬騿栴},上面已經(jīng)介紹,在不能操控的豆瓣數(shù)據(jù)上,使用的是。 項目地址 在線演示 不識廬山真面目,只緣身在此山中。 大概一個月前,開源了Vue重構(gòu)豆瓣移動端的項目,效果還可以,收到了很多小伙伴的反饋,話說是要寫一些文章的,但遲遲沒有動筆,估計小伙伴們等的花都謝了,拖延癥是病,需要治...

    lijinke666 評論0 收藏0
  • 前端vue系列-起始篇 vue的基本認(rèn)知

    摘要:管理后臺,日常就是提交各種表單了,這部分現(xiàn)有的方案,比如表單提交或者收集信息提交。,可以用于前端開發(fā)的工程構(gòu)建。帶了人的前端團(tuán)隊,你的精力開始在配合公司其他部門做用戶數(shù)據(jù)增長了。開始考慮使用的。? ? ? ?hi,大家伙,我是佛系大大,很高興與你們一起溝通,學(xué)習(xí),進(jìn)步。 ? ? ? ?很久不更新博客了,現(xiàn)在回來再寫博客,盡然是有些懷念的感覺,幸福的感覺。因為寫博客,內(nèi)心會很寧靜,沉浸在自己的...

    I_Am 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<