1. 程式人生 > >JavaScript設計模式之代理模式

JavaScript設計模式之代理模式

代理模式

代理模式合併多個複雜業務請求,減輕web伺服器壓力

頁面框架

<p><span id='toggle-all'>Toggle Checked</span></p>
<ol>
  <li>
    <input type="checkbox" checked>
    <a href="http://new.music.yahoo.com/videos/--2158073"></a>
  </li>

  <li>
    <input type="checkbox"
checked> <a href="http://new.music.yahoo.com/videos/--2158073"></a> </li> <li> <input type="checkbox" checked> <a href="http://new.music.yahoo.com/videos/--2158073"></a> </li> <li> <input type="checkbox" checked> <a href="http://new.music.yahoo.com/videos/--2158073"
></a> </li> <li> <input type="checkbox" checked> <a href="http://new.music.yahoo.com/videos/--2158073"></a> </li> </ol> //事件處理函式 $ = document.getElementById; $('vids').onclick = function (e) { Var id,src; e = e || windows.event; Src = e.target || e.srcElement; if
(src.nodeName !== 'A'){ return; } if(typeof e.preventDefault === 'function'){ e.preventDefault(); } e.returnValue = false; id = src.href.split('--')[1]; if(src..className === 'play'){ src.parentNode.innerHtml = videos.getPlayer(id); return; } src.parentNode.id = 'v' + id; videos.getInfo(id); } $('toggle-all').onclick = function (e) { var I,hrefs,max,id; hrefs = $('vids').getElementByTagName('a'); max = hrefs.length; for(I = 0;i < max;I++){ if(hrefs[I].className === 'play'){ continue; } if(hrefs[I].parentNode.firstChild.checked){ continue; } id = hrefs[I].href.split('--')[1]; hrefs[I].parentNode.id = 'v' + id; videos.getInfo(id); } } //videos物件 Videos = { getPlayer: function (id){...}, updateList: function (data){...}, getInfo: function (id){ var info = $('info' + id); if(!info){ proxy.makeRequest(id,this.updateList,vedios); return; } if(info.style.display === 'none'){ info.style.display = ''; }else{ info.style.display = 'none'; } } }; //http物件 //新增一個指令碼,指令碼內容為產生JSONP格式的請求到Yahoo!的YQL Web伺服器 //sql未YQL查詢語言(該語言類似sql語言) Var http = { makeRequest: function (ids,callback) { var url = 'http://query.yahooapis.com/v1/public/yql?q=', format = 'select * from music.video.id where ids IN (%ID%)', handler = 'callback=' + callback, script = document.createElement('script'); sql = sql.replace('%ID%',ids.join('","')); sql = encodeURIComponent(sql); document.body.appendChild(script); } }; //現在加入proxy代理物件,videos物件會先呼叫proxy,然後proxy50ms的快取佇列之後會集中處理http請求,訪問http物件 Proxy = { ids: [], delay: 50,//快取佇列的快取時間 timeout: null, callback: null, context: null, makeRequest: function (id,callback,context){ this.ids.push(id); this.callback = callback; this,context = context; //設定超時時間 if(timeout){ setTimeout(function () { proxy.flush(); },this.delay); } }, flush: function () { http.makeRequest(ids,'proxy.callback'); //清除緩衝佇列 this.timeout = null; this.ids = []; }, handler: function (data) { //不同於videos的updateList回撥,handler可以處理多個數據,適用於緩衝佇列的多個http請求資料處理 var I,max; if(parseInt(data.query.count,10) === 1){ //單個視訊 proxy.callback.call(this.context,data.query.result.Video); return; } for(I = 0, max = data.query.result.Video.length;;I < max;i++){ //多個視訊 proxy.callback.call(this.context,data.query.result.Video[i]); } } };