所謂條條大路通羅馬,但若是讓我來設計通向羅馬的各類大路,我至少會作兩件事情:前端
① 讓羅馬只有一個入口web
② 讓羅馬只有一個出口ajax
這樣作的好處是,不管你路從哪來,我能夠統一在入口處給你打上各類標誌,我也能夠在你離開羅馬時給你留點記念。固然羅馬天然不僅一個出口入口,可是每一個出口入口必定有一套相同的規定,不然就會出問題。數據庫
具體到當今的工做場景,高速公路又是一個收口的好例子,進入高速公路時候得通過收費站作點標誌,離開時候也會作點操做,若是沒有這種收口,不管是繳費工做,流量統計或者其餘都是沒法統計的。緩存
正常生活中有各類收口的行爲,咱們會發現,收口雖然會讓效率變低,但卻能夠更好的管理,一樣的道理是能夠應用到前端乃至整個程序開發的,今天咱們就來聊一聊前端中的各類收口。服務器
文中僅僅是我的經驗,若是有誤請指出。微信
前面咱們說了工做中收口帶來的各類好處(壞處是面向用戶會增長成本),而咱們前端開發中會有哪些收口呢?app
通常來講,對於前端,請求收口便是ajax的收口,而常常有朋友會問我一些問題:重複的請求如何讓他第二次不請求呢?dom
其實解決這個問題很簡單的一個方案就是對ajax進行收口處理:webapp
1 var ajaxProxy = function(params) { 2 //作一些額外的工做,好比處理params參數 3 $.ajax(params) 4 };
這裏的處理辦法就是統一在底層篡改ajax success回調,對數據作一層處理,然而對請求接口進行收口的好處遠遠不止於此。
首先,咱們能夠對每一個請求的請求參數在底層加入額外參數,好比咱們與server端約定,每次請求咱們都會額外帶一個head參數,會攜帶一些非業務公共數據:
1 head: { 2 channel: 'webapp', //渠道標誌 3 version: '2.2.0', //版本信息 4 ct: 3, //平臺信息 5 extend: null//可能須要的擴展信息 6 }
每個請求若是額外帶這些信息的話,能夠解決不少問題:
① server端知道當前請求來源於哪一個渠道(SEM渠道、微信流量入口、搜索流量入口......)、哪個版本、哪個平臺(iOS、Android、H5),可能Server就能對這個請求作定製化處理了
② 協助KPI考覈,好比市場人員要推廣本身的產品,然後臺要統計他今天成功推廣多少單,就會爲這個用戶生成一個二維碼,具體的url是這樣的:
http://domain.com?channel=yexiaochai
那麼,個人沒一個請求(包括生成訂單)都將把channel字段發給Server端,Server若是存於數據庫,天天就能很簡單生成全部用戶的訂單完成量
③ SEM渠道是一大流量來源(買搜索關鍵詞),若是咱們想拿到每個關鍵詞對咱們系統每個頁面的訪問量的話,也能夠在這種公共請參數作處理
④ 根據以上功能,咱們甚至能夠根據這些特性配合通用的統計平臺創建初略的前端漏斗模型
通常來講,每一個請求接口,server端返回的數據有一固定格式:
1 { 2 data: {},//真實數據 3 errno: 0,//錯誤碼 4 msg: "success"//信息 5 }
正常的邏輯咱們只須要處理data數據便可,而錯誤碼不爲0的狀況,咱們可能是彈一個toast提示msg錯誤信息,因此咱們會統一修改請求的回調,固然也會對一些錯誤碼作特殊處理(未登錄、未受權),好比這樣:
1 //統一處理請求返回數據 2 var commonDataHandler = function (data) { 3 //記錄請求返回 4 if (!data) { 5 showToast('服務器出錯,請稍候再試'); 6 return; 7 } 8 if (_.isString(data)) data = JSON.parse(data); 9 //正常狀況,不執行其它邏輯 10 if (data.errcode === 0) return true; 11 12 //處理請求未登錄的特殊狀況 13 if (data.errcode == ERROR_CODE['NOT_LOGIN']) { 14 showToast(data.errmsg, function () { 15 //執行統一邏輯,跳到登錄頁面,要求登錄成功後跳回來 16 }); 17 return false; 18 } 19 //處理其它須要特殊處理的錯誤碼,須要業務開發對接口作定製化,將處理邏輯寫到具體頁面 20 if(this.errCodeCallback[data.errcode]) { 21 this.errCodeCallback[data.errcode](data.errcode, data.errmsg, data); 22 return false; 23 } 24 //通用錯誤處理,直接彈出toast 25 if (window.APP && data && data.errmsg) window.APP.showToast(data.errmsg, this.errorCallback); 26 return false; 27 };
固然,最開始說的重複請求再也不請求也能夠作到這個地方,可是具體操做會有不少細節點須要考慮。
由於hybrid模式的出現,前端除了ajax外,可能會有更多的選擇,好比在Native容器中,前端便不使用ajax發出請求,直接由Native代理髮出,若是請求沒作封口的話,便須要改動全部的業務代碼,這個是十分不科學的。
這裏僅僅是提一個小小的點想向各位說明程序收口的重要性,其實咱們程序中不少細小的點皆須要作收口處理。
咱們前面說過若是不想重複請求便須要使用緩存技術,對應到前端是localstorage,不管什麼時候,咱們使用緩存都必須考慮如何更新和緩存過時問題,這個時候咱們須要對齊收口。
在作單頁應用時,咱們爲了避免破壞路由,須要對跳轉作收口,咱們甚至須要對window.location這種跳轉作收口處理,得封裝爲一個函數。
關於實際工做中的收口的例子太多了,細小入setTimeout的收口,事件機制的收口,大到帳號體系、錢包體系等的收口處理,咱們在實際工做中應該具有這種收口的思想。