JavaScript設計模式之代理模式
阿新 • • 發佈:2019-01-04
代理模式
代理模式合併多個複雜業務請求,減輕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]);
}
}
};