摘要:虛擬代理和函數(shù)節(jié)流的思想是一樣的,將用戶對性能的的傷害降低到最低。虛擬代理上面的保護代理闡述了怎樣去拒絕請求,而虛擬代理的原則是收集請求來者不拒他的出發(fā)點和保護代理的是一樣的,都是為了節(jié)省請求的開支。
What"s the proxy pattern?
代理模式其實就是將違反單一性原則的類給抽離出來,盡量滿足開放和封閉的原則。 相當于一個類的行為只是一種,但是你可以給這個類添加額外的行為。比如: 一個工廠制造傘,你可以給這個工廠設置一個代理,提供訂單,運貨,淘寶網(wǎng)店等多種行為。當然,里面還有最關鍵的一點就是,這個代理能把一些騙紙和忽悠都過濾掉,將最真實最直接的訂單給工廠,讓工廠能夠放心的讓工人加班,順利的發(fā)年終獎.
!!!說人話:
就是將你的本體請求,放在代理的懷抱里,讓他來幫你擋風擋雨。
圖片延遲加載是指,圖片的加載應該在頁面全部加載完后,再去加載。這樣能夠提高加載的速度和網(wǎng)頁的體驗性。實際操作就是,將原來網(wǎng)頁的src獨立出來,將原來圖片使用一個loading.gif代替,然后再js里面手動創(chuàng)建個img去加載這個src,當加載完后把src替換就可以了。
沒有使用加載時
var delayload = (function(){ var img = document.querySelector("#img"); img.src = "loading.gif"; var newImg = document.createElement("img"); newImg.onload = function(){ img.src = newImg.src; } return function(src){ newImg.src = src; } })(); delayload("jimmy.jpg");
這樣寫,我給滿分(在沒有產(chǎn)經(jīng)這個生物的前提下).
現(xiàn)在,假設有一個初級產(chǎn)經(jīng)(還沒有進化那種)
她有一個需求: 我不要你的這個loading.gif圖片,你換一個。
恩,好沒問題。 (不過就是換一下src而已)
她又有一個需求: 你這loading.gif好丑,你弄一個純色的.
MD~ 搞什么,你這樣我很為難誒,我邏輯都變了,你讓我這個改。。
所以,為了應對產(chǎn)經(jīng)這個神奇的物種,推薦使用代理模式這個岡本,去降服產(chǎn)經(jīng).
來,上岡本
//將背景圖設置,和圖片加載的src修改分開 var delayload = (function(){ var img = document.querySelector("#img"); return { setSrc:function(src){ img.src = src; } } })(); var proxy = (function(){ var img = document.createElement("img"); img.onload = function(){ delayload.setSrc(img.src); } return { setSrc:function(src){ delayload.setSrc("loading.gif"); img.src = src; } } })(); proxy.setSrc("jimmy.jpg");
恩,如果產(chǎn)經(jīng)要求換圖片,好解決,換一下loading.gif就over了.如果產(chǎn)經(jīng)要求換成純色的。也行。 再加一個方法.
var delayload = (function(){ var img = document.querySelector("#img"); return { setSrc:function(src){ img.src = src; }, setBg:function(color){ img.style.backgroundColor = color; } } })(); var proxy = (function(){ var img = document.createElement("img"); img.onload = function(){ delayload.setSrc(img.src); } return { setSrc:function(src){ delayload.setBg("red"); //只需要替換這一句 img.src = src; } } })(); proxy.setSrc("jimmy.jpg");
使用代理就可以在,最大限度降低代碼改動的情況下,完成需求。
當然,
如果有一天神奇生物又提出一個需求:
親,我們現(xiàn)在寬帶升級了,有100M了誒,你可以把加載去掉了吧,直接讓用戶一下就用看見圖片了哦。
(呵呵~我丟你雷姆)
沒事,誰叫我有代理模式(岡本)嘞。改~
神奇的事發(fā)生了.
var proxy = (function(){ var img = document.createElement("img"); img.onload = function(){ delayload.setSrc(img.src); } return { setSrc:function(src){ //刪除~ img.src = src; } } })(); proxy.setSrc("jimmy.jpg");
仔細觀察就可以發(fā)現(xiàn),我接口沒改,對象沒動,只是將delayload.setBg("red")刪除了。
加載功能還在,只是我使用代理傳了一層。66666
通常來說,代理其實就是本體的一個影子,我有的行為你應該都有,我能sit,代理也能sit. 所以為了不讓用于迷惑,這里有一個需求就是,代理的接口名應該和本體的接口名一致,就和上面的setSrc一樣.
但通常這是個主要是針對java的靜態(tài)語言的要求。因為在js里面沒有實現(xiàn)接口的繼承,而且在js里面,函數(shù)是名副其實的一等公民,所以這里對于代理的一直性要求就沒有這么高了。
上面其實可以改寫為:
var setImg = (function(){ var img = document.querySelector("#img"); return function(src){ newImg.src = src; } })(); var proxyImg = (function(){ var newImg = document.createElement("img"); newImg.onload = function(){ setImg(newImg.src); } return function(src){ setImg("loading.gif"); newImg.src = "jimmy.jpg"; } })
但本人推薦上面那種使用接口的形式,這樣拓展性比較強,而且易于復用.
保護代理和虛擬代理這其實很好理解,保護代理就是起到保護作用,用來過濾掉一下不必要的請求,將真正需要的遞給本體。
虛擬代理和函數(shù)節(jié)流的思想是一樣的,將用戶對性能的rape的傷害降低到最低。就像送快遞一樣,一件一件的送,這個公司是不是傻~ 所以為了生存,快遞公司會當物品積攢到一定程度后才會讓快遞哥騎著小電驢穿梭在神州大地上。
保護代理
//譬如,驗證用戶名是否唯一 //這里我們應用,保護代理的思想,如果用戶名是不合法的,則不會將該請求給本體執(zhí)行 var checkUser = function(name){ $.ajax({ url:"xxxxx", type:"POST", contentType:"application/json", data:JSON.stringify({ name:name //用戶名 }) }) } var proxy = (function(){ var user = document.querySelector("#username"); return function(){ var userName = user.value; var errMsg = detect(userName,["NotEmpty","isUserName"]); //利用策略模式,驗證. if(errMsg){ console.log(errMsg); return; } checkUser(userName); } })();
可以清楚的看到,如果你的用戶名格式不正確,這個請求是不會達到本體的。直接回在proxy里面被攔截掉。所以一個很好的代理(保護代理),能讓你的請求100%用在刀刃上。
虛擬代理
上面的保護代理闡述了怎樣去拒絕請求,而虛擬代理的原則是收集請求(來者不拒). 他的出發(fā)點和保護代理的是一樣的,都是為了節(jié)省請求的開支。
比如: 一個在線的編輯器,他是怎樣同步你的內容呢?不會是,你內容一改變就發(fā)送一起請求同步吧。這個想法顯然不切實際。如果這樣,我每天沒事都會打開這個編輯器,把asfdsafdsafsad...在里面敲上幾分鐘。保證分分鐘弄死他的服務器。所以一般,我們會使用虛擬代理來接受你的請求。
var send = function(article) { return $.ajax({ url: xxx, type: "POST", contentType: "text/plain", data: article }) } var proxy = (function() { var content = document.querySelector("#article"), timer; return function() { var article = content.value; if (timer) { //不覆蓋已經(jīng)發(fā)送的請求 return; } timer = setTimeout(function() { send(article) .then(function() { //執(zhí)行完成再處理 clearTimeout(timer); timer = null; }) }, 2000); } })(); setTimeout(function(){ proxy(); },2000); //定時發(fā)送請求
就算你手速再快,我就只能2s發(fā)一次。 但這只是一個比較簡單的實例。如果大家感興趣可以研究一下,作業(yè)部落這個編輯器,他這個markdown同步和體驗交互式我迄今為止用過應該算最好的一個了吧~
緩存代理這個應該是應用最多的一個代理方式了,這種方式能夠真正解決運算時間問題,網(wǎng)絡不暢問題,離線問題。
搬一個例子過來吧。
計算乘積問題
function fb(num){ if(num<=1){ return 1; } return num*fb(--num) } //緩存代理出場了 var cProxy = (function(){ var cache = {}; return function(num){ if(cache[num]){ console.log(`this is cache ${cache[num]}`); return cache[num]; } return cache[num] = fb(num); } })(); //測試 console.log(cProxy(4)); //24 cProxy(4); //"this is cache 24"
恩,完美。 我們知道階乘是比較累的一個計算方法,如果某天你的leader需要你計算很多次fb(2000)。用戶的電腦也吃不消啊,所以為了體驗,緩存代理是你百分百女友,好好珍惜。
當然,緩存代理并不只有這一點用途,比如需要重復獲取網(wǎng)頁中大部分數(shù)據(jù)的時候,就可以考慮使用緩存代理。前端工作者,99.9999%的應該都會遇見分頁的問題(請不要告訴我你的分頁是同步方式). 當我們點擊一個頁面的時候,獲取后臺的數(shù)據(jù),然后再由我恩渲染到頁面上,這是這樣一個流程。 首先,渲染流程可以復用,那數(shù)據(jù)的復用性該怎么做呢?
恩,猜到了吧,就是使用cache進行一個緩存,然后如果下次獲取分頁的頁碼一致的話,就可以直接使用該數(shù)據(jù)了。
//向后臺發(fā)請求,獲取當前頁面的數(shù)據(jù) // http.getPage(page); var pageProxy = (function(){ var cache = {}; return function(fn){ //fn作為處理頁碼數(shù)據(jù)的函數(shù) var pageData = cache[page]; if(pageData){ return fn(pageData); //返回制定頁碼的數(shù)據(jù) } http.getPage(page) //獲取制定頁碼的數(shù)據(jù) .then((data)=>{ cache[page] = data; //存放數(shù)據(jù) fn(data); }) } })();
最后再說一句吧,由于代理寫起來需要更多的邏輯和代碼,如果你的產(chǎn)經(jīng)沒有什么需求的話,不用代理也是行得通的。還有就是,用不用代理和你原來的本體執(zhí)行的業(yè)務邏輯是完全分開的,即,如果后期產(chǎn)經(jīng)有什么需求,或者你對自己的代碼不滿意,重構的時候,再添加代理,這種方式也是很推薦的。
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/78492.html
摘要:因此,另一種解決辦法像這樣的工具,則只是將和進行了結合,其功能尤其關注日志管理,比如格式檢查,日志語法分析,數(shù)據(jù)改進地址地理位置信息,元數(shù)據(jù)標簽等以及日志路由。 由Rancher社區(qū)維護的應用商店最近迎來了兩個明星項目——SPM 和 Logsene,來自Sematext的監(jiān)控與日志工具。如果你已經(jīng)熟悉Logstash,Kibana,Prometheus,Grafana這些監(jiān)控或日志解決...
摘要:內置了三種發(fā)送網(wǎng)絡請求的方式和。轉換二進制為發(fā)送到目前為止,不能發(fā)送非序列化的數(shù)據(jù),所以,要發(fā)送二進制數(shù)據(jù),采用編碼的字符串是個不錯的選擇。在最新版本的層也已經(jīng)支持協(xié)議來傳輸二進制文件,但是,相應的原生平臺的網(wǎng)絡模塊暫時還不支持。 端) 本文原創(chuàng),轉載請注明作者及出處 在使用React Native開發(fā)中,我們熟練的采用JavaScript的方式發(fā)送請求的方式發(fā)送一個請求到服務端,但是...
摘要:引用計數(shù)這是最簡單的垃圾收集算法。然而,引用計數(shù)算法考慮到它們互相都有至少一次引用,所以它們不會被回收。事件代理發(fā)生在冒泡階段。為時取消事件默認行為,為時取消時間傳播通常利用事件冒泡機制托管事件處理程序提高程序性能。 JS延遲加載的方式有哪些? JS的延遲加載有助與提高頁面的加載速度。defer和async、動態(tài)創(chuàng)建DOM方式(用得最多)、按需異步載入JSdefer:延遲腳本。立即下載...
閱讀 2685·2021-11-18 10:02
閱讀 3416·2021-09-28 09:35
閱讀 2595·2021-09-22 15:12
閱讀 754·2021-09-22 15:08
閱讀 3117·2021-09-07 09:58
閱讀 3476·2021-08-23 09:42
閱讀 737·2019-08-30 12:53
閱讀 2086·2019-08-29 13:51