ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScript デザイン パターンを学ぶ - プロキシ パターン_JavaScript スキル

JavaScript デザイン パターンを学ぶ - プロキシ パターン_JavaScript スキル

WBOY
WBOYオリジナル
2016-05-16 15:20:241079ブラウズ
  • 有名人はマネージャーによって代表されます。有名人にコマーシャルパフォーマンスの司会を依頼する場合は、エージェントに連絡するだけで済みます。エージェントはコマーシャルパフォーマンスの詳細と報酬について交渉し、その後、有名人に契約書に署名してもらいます。

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");

プロキシ パターンを使用する利点: 各関数に単一の関数を持たせ、オブジェクト設計の「単一責任原則」を実現します。

3. ファイルの同期

ファイル同期機能を実行しているとします。チェックボックスを選択すると、対応するファイルが別のサーバーに同期されます。


<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>
チェックボックスを選択せず​​に一度同期するのは明らかに不合理です。なぜなら、Web 開発において最大のオーバーヘッドはネットワーク リクエストだからです。


解決策: プロキシ機能を使用して、一定期間内のリクエストを収集し、それらを一度にサーバーに送信します。

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);
    }
  }
}

4. キャッシュプロキシ – 積の計算 (シーケンスは全く同じです)

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));
この記事が JavaScript プログラミングを学習するすべての人に役立つことを願っています。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。