1. 定義
プロキシ パターン: オブジェクトへのアクセスを制御するために、オブジェクトのサロゲートまたはプレースホルダーを提供します。
エージェントは次のように分類されます: 保護エージェントと仮想エージェント
保護エージェント: は、対象オブジェクトに対する異なる権限を持つオブジェクトのアクセスを制御するために使用されます。 JavaScript では、誰がオブジェクトにアクセスしたかを判断することが難しいため、保護エージェントは困難です。実装する。
2. イメージのプリロード (最も一般的な仮想エージェント アプリケーションのシナリオ)
画像のプリロードは一般的な技術です。img タグ ノードの src 属性を直接設定すると、画像が大きすぎるか、ネットワークが貧弱であるために、画像の位置が一定期間空白になることがよくあります。一般的なアプローチは、事前に読み込み中の画像をプレースホルダーとして使用し、画像が読み込まれた後にその画像を img ノードに埋め込むことです。
実装原則:
Image オブジェクトを作成します: var a = new Image();
Image オブジェクトの src を定義します: a.src = “xxx.gif”;
これは、ブラウザーの画像をキャッシュすることと同じです。
画像オブジェクトの complete 属性を通じて、画像が読み込まれたかどうかを確認できます。各 Image オブジェクトには complete 属性があり、onload、onerror、onabort イベントのいずれかが発生すると、その時点で属性値が終了します。 complete 属性は true です。
(1) 非プロキシ実装
var myImage = (function() { var imgNode = document.createElement("img"); document.body.appendChild(imgNode); var img = new Image(); img.onload = function() { imgNode.src = img.src; }; return { setSrc: function(src) { imgNode.src = "./images/loading.gif"; img.src = src; } } })(); myImage.setSrc("./images/originImg.png");
(2) プロキシ実装
// 创建图片DOM var myImage = (function() { var imgNode = document.createElement("img"); document.body.appendChild(imgNode); return { setSrc: function(src) { imgNode.src = src; } }; })(); // 代理 var proxyImage = (function() { var img = new Image(); img.onload = function() { myImage.setSrc(this.src); // this指向img!img加载完成后,将img.src传递给myImage }; return { setSrc: function(src) { myImage.setSrc("./images/loading.gif"); // loading img.src = src; } }; })(); proxyImage.setSrc("./images/originImg.png");
ファイル同期機能を実行しているとします。チェックボックスを選択すると、対応するファイルが別のサーバーに同期されます。
<body> <input type="checkbox" id="1" />文件1 <input type="checkbox" id="2" />文件2 <input type="checkbox" id="3" />文件3 <input type="checkbox" id="4" />文件4 <input type="checkbox" id="5" />文件5 <input type="checkbox" id="6" />文件6 </body>
解決策: プロキシ機能を使用して、一定期間内のリクエストを収集し、それらを一度にサーバーに送信します。
var synchronousFile = function(id) { console.log("开始同步文件,id为:" + id); }; var proxySynchonousFile = (function() { var cache = [], // 保存本次需要同步文件的id timer; // 定时器 return function(id) { cache.push(id); if(timer) { // 不要覆盖已经启动的定时 return; } timer = setTimeout(function(){ synchronousFile(cache.join(",")); clearTimeout(timer); timer = null; cache.length = 0; // 清空缓存 }, 2000); } })(); var checkboxs = document.getElementsByTagName("input"); for(var i = 0, c; c = checkboxs[i]; i++) { c.onclick = function() { if(this.checked === true) { proxySynchonousFile(this.id); } } }
var mult = function() { var result = 1; for(var i = 0, l = arguments.length; i < l; i++) { result= result * arguments[i]; } return result; }; var proxyMult = (function() { var cache = {}; // {"1,2,3": 6} return function() { var args = Array.prototype.join.call(arguments, ","); if(args in cache) { return cache[args]; } return cache[args] = mult.apply(this, arguments); } })(); console.log(proxyMult(1, 2, 3)); // 改造: var proxyFactory = function(fn) { var cache = {}; return function() { var args = Array.prototype.join.call(arguments, ","); if(args in cache) { return cache[args]; } return cache[args] = fn.apply(this, arguments); } }; console.log(proxyFactory(mult)(1, 2, 3));