您好,登錄后才能下訂單哦!
本篇內容介紹了“javascript設計模式中的訂閱者模式怎么實現”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
代理模式是為一個對象提供一個代用品或占位符,以便控制對它的訪問。它的用處就是當客戶不方便直接訪問一個對象或者不滿足需要的時候,提供一個替身對象來控制對這個對象的訪問。通俗來講就是,代理是一個中間人,負責在客戶和賣家之間傳遞信息,將沒用的信息過濾,將有利于交易成功的信息傳遞給賣家,從而加大交易的成功率。
現在我們來通過一個小明給女神送花的例子來實現代理模式。
沒有使用代理模式
let Flower = function () {}; let xiaomingFirst = { sendFlower ( target ) { let flower = new Flower(); target.receiveFlower( flower ); } } let A = { receiveFlower ( flower ) { console.log('收到花') } } xiaomingFirst.sendFlower(A);
使用代理模式重構
設定一個需求:AA 為小明的女神,AA 在心情好的時候接受小明花的幾率更大,而 B 是 AA 和小明的好朋友,因此小明將花送給 B,讓 B 在 AA 心情好時轉告自己的心意。
分析:重構后的代碼增加了一個新的對象 B , 此時 B 為 AA 的代理,B 監聽 AA 的好心情,代碼中假定5秒后 AA 心情變好,B 將花送出。
let xiaomingSencend = { sendFlower ( target ) { let flower = new Flower(); target.receiveFlower( flower ); } } let AA = { receiveFlower () { console.log('收到花'); }, listenGoodMood ( fn ) { setTimeout(()=>{ fn(); }, 5000); } } let B = { receiveFlower ( flower ) { AA.listenGoodMood( ()=>{ AA.receiveFlower( flower ); } ); } } xiaomingSencend.sendFlower(B);
上述代碼中代理模式可能顯得不那么重要,但是體現了代理的思想,假如女神有一些要求,給他送花的男生必須帥而有錢,但又不能顯得那么勢力,因此代理可以幫其過濾掉這些不符合要求的男生,減少自己的許多麻煩,還能保持自己的美好形象這就是代理的用處。再者說,買一朵花很昂貴,而不是單單 new 這么簡單,男生不想浪費自己的錢,因此想先確定女神是否接受自己的花,便讓代理幫忙詢問,如果女神接受則讓代理幫忙買一朵送給女神,這樣減少了男生的損失但也達成了目的,這便引出了以下兩種代理模式。
保護代理:本體的要求直接在代理中實現,過濾掉不符合的要求的訪問者對本體的請求
虛擬代理:將一些開銷很大的操作等到準備向本體請求時候再實現(主要用于實際開發)
1. 虛擬代理實現圖片預加載
分析:先加載本地圖片,然后開始發起請求獲取圖片,當圖片加載獲取成功后,再調用 myImage 將圖片替換預加載時顯示的圖片。
let myImage = function () { let img = document.createElement('img'); document.body.appendChild(img); return { setSrc ( src ) { img.src = src; } } }(); proxyImage = function () { let img = new Image; img.onload = function () { myImage.setSrc( this.src ); } return { setProxyImage( src ) { myImage.setSrc("https://cache.yisu.com/upload/information/20220112/112/58.jpg@1280w_1l_2o_100sh.jpg"); // 此處為加載 loading 圖片,用來占位,本地圖片(作者使用網絡圖片) img.src = src; } } }(); proxyImage.setProxyImage("https://cache.yisu.com/upload/information/20220112/112/59.jpg@1280w_1l_2o_100sh.jpg");
2. 緩存代理
分析:在代理中將本體計算的結果進行緩存,如果下次再遇到同樣的請求,直接從緩存中獲取,減少對本體的訪問,減少性能消耗。
// 計算乘積的函數 let mult = function (...arg) { console.log('我執行了') let m = 1; for(let i = 0,l = arg.length; i <l; i++){ m *= arg[i]; } return m; } // 緩存代理 let proxyMult = function( fn ) { let cache = {}; return function (...arg) { let argS = arg.join(','); if( cache[argS] ) { return cache[argS]; } return cache[argS] = fn.apply( this, arg); } }; let proxymult = proxyMult(mult); console.log(proxymult(1,2,4))
3. 虛擬代理合并 Http 請求
使用場景:點擊復選框向服務器發起請求同步文件,每次點擊復選框便發起一次請求,造成巨大網絡開銷,此時我們優化的方式為,將想同步的文件緩存下來,在 3 秒后通過一次請求發送到服務器。
<input type="checkbox" >1 <input type="checkbox" >2 <input type="checkbox" >3 <input type="checkbox" >4 <input type="checkbox" >5 <input type="checkbox" >6 <input type="checkbox" >7 <input type="checkbox" >8 <script> // 同步文件 let synchronousFile = function ( id ) { console.log("開始同步文件" + id); } // 代理實現同步文件 let proxySynchronousFile = function ( ) { let cache = []; let time; return function ( id ) { cache.push( id ); if( time ) { return; } time = setInterval(() => { synchronousFile(cache.join(',')); clearInterval(time); time = null; cache.length = 0; }, 3000); } }() // 添加點擊執行 let checkboxList = document.getElementsByTagName('input'); for(let i = 0, l = checkboxList.length; i < l; i++) { checkboxList[i].onclick = function() { if( this.checked === true ) { proxySynchronousFile(i+1); } } }
意義:首先我們引入面向對象設計原則,單一職責原則,一個對象應該盡可能少的承擔職責,最好是一個,如果承擔職責過多,會提高代碼的耦合度,從而導致脆弱和低內聚的設計。當變化發生,設計可能遭到意外破壞,即使實現同樣需求可以將代碼封裝到一個函數中,但是最好的處理措施是引入代理模式
要求:代理和本體接口要一致,在任何使用本體地方都可以用代理來代替
“javascript設計模式中的訂閱者模式怎么實現”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。