検索
ホームページウェブフロントエンドjsチュートリアルJavascript設計パターンの複数の実装例 オブザーバーパターン_JavaScriptスキル

はじめに

オブザーバー モードは、パブリッシュ/サブスクライブ モード (パブリッシュ/サブスクライブ) とも呼ばれ、1 対多の関係を定義し、複数のオブザーバー オブジェクトが特定のトピック オブジェクトのステータスを同時に監視できるようにします。トピック オブジェクトが変更されると、すべてのオブザーバー オブジェクトが通知され、オブジェクト自体が自動的に更新されます。

オブザーバー パターンを使用する利点:

1. 単純なブロードキャスト通信をサポートし、サブスクライブされたすべてのオブジェクトに自動的に通知します。
2. ページがロードされた後、ターゲット オブジェクトはオブザーバーと動的な関係を簡単に持つことができるため、柔軟性が向上します。
3. ターゲットオブジェクトとオブザーバーの間の抽象的な結合関係は、独立して拡張および再利用できます。

テキスト (バージョン 1)

JS でのオブザーバー パターンの実装は、コールバックを通じて実現されます。まず、subscribe、unsubscribe、publish の 3 つのメソッドを含む pubsub オブジェクトを定義します。

コードをコピー コードは次のとおりです:

var pubsub = {};
(関数 (q) {

var topic = {}, // コールバック関数に格納される配列
subUid = -1;
//メソッドを公開
q.publish = 関数 (トピック, 引数) {

if (!topics[トピック]) {
return false;
}

setTimeout(function() {
varsubscribers = トピック[トピック],
len = 購読者.length : 0;

しながら (len--) {
subscribers[len].func(topic, args);
}
}, 0);

true を返します;

};
//サブスクリプションメソッド
q.subscribe = function (topic, func) {

if (!topics[トピック]) {
トピック[トピック] = [];
}

var token = ( subUid).toString();
トピック[トピック].push({
トークン: トークン、
func: func
});
トークンを返す;
};
//購読を解除する方法
q.unsubscribe = 関数 (トークン) {
for (トピック内の変数 m) {
if (トピック[m]) {
for (var i = 0, j = topic[m].length; i If (トピックス[m][i].token === トークン) {
トピック[m].splice(i, 1);
トークンを返す;
}
}
}
}
return false;
};
} (pubsub));

次のように使用します:

コードをコピー コードは次のとおりです:

// ぜひ購読してください
pubsub.subscribe('example1', 関数 (トピック, データ) {
console.log(トピック ": " データ);
});

//通知を公開
pubsub.publish('example1', 'hello world!');
pubsub.publish('example1', ['test', 'a', 'b', 'c']);
pubsub.publish('example1', [{ 'color': 'blue' }, { 'text': 'hello'}]);

どうですか?すごく使いやすいんじゃないでしょうか?しかし、この方法には問題があります。つまり、購読を解除する方法がないということです。購読を解除したい場合は、購読解除の名前を指定する必要があるため、別のバージョンを考えてみましょう:

コードをコピーします コードは次のとおりです:

//サブスクライブを解除する変数にサブスクリプションを割り当てます
var testSubscription = pubsub.subscribe('example1', function (トピック, データ) {
console.log(トピック ": " データ);
});

//通知を公開
pubsub.publish('example1', 'hello world!');
pubsub.publish('example1', ['test', 'a', 'b', 'c']);
pubsub.publish('example1', [{ 'color': 'blue' }, { 'text': 'hello'}]);

//購読を解除
setTimeout(function() {
pubsub.unsubscribe(testSubscription);
}, 0);

//再度パブリッシュして、情報がまだ出力できるかどうかを確認します
pubsub.publish('example1', 'こんにちは! (これは失敗します)');

バージョン 2

プロトタイプの特性を使用してオブザーバー パターンを実装することもできます。コードは次のとおりです。

コードをコピー コードは次のとおりです:

function Observer() {
This.fns = [];
}
Observer.prototype = {
購読: function (fn) {
This.fns.push(fn);
}、
購読解除: function (fn) {
this.fns = this.fns.filter(
関数 (el) {
If (el !== fn) {
                                                                                                                                                                                } } );
}、
更新: function (o, thisObj) {
varscope = thisObj || window;
This.fns.forEach(
関数 (el) {
el.call(scope, o);
} );
}
};

//テスト
var o = 新しいオブザーバー;
var f1 = 関数 (データ) {
console.log('ロビン: ' データ '、すぐに作業を始めてください!');
};

var f2 = 関数 (データ) {
console.log('ランドール: ' データ '、給料を増やすように頼んでください!');
};

o.subscribe(f1);
o.subscribe(f2);

o.update("トムが帰ってきた!")

// f1 の購読を解除
o.unsubscribe(f1);
// 再度検証します
o.update("トムが帰ってきた!");

フィルターまたは forEach 関数が見つからないというメッセージが表示された場合は、ブラウザーが新しくなく、現在新しい標準関数をサポートしていない可能性があります。次の方法を使用して自分で定義できます。

コードをコピーします コードは次のとおりです:

if (!Array.prototype.forEach) {
Array.prototype.forEach = function (fn, thisObj) {
varscope = thisObj || window;
for (var i = 0, j = this.length; i fn.call(scope, this[i], i, this);
}
};
}
if (!Array.prototype.filter) {
Array.prototype.filter = function (fn, thisObj) {
varscope = thisObj || window;
var a = [];
for (var i = 0, j = this.length; i If (!fn.call(scope, this[i], i, this)) {
続行;
}
a.push(this[i]);
}
return a;
};
}

バージョン 3

複数のオブジェクトにオブザーバーのパブリッシュおよびサブスクライブ関数を持たせたい場合は、一般的な関数を定義し、この関数の関数をオブザーバー関数が必要なオブジェクトに適用できます。コードは次のとおりです。

コードをコピーします コードは次のとおりです:
//一般的なコード
var オブザーバー = {
//購読
AddSubscriber: 関数 (コールバック) {
This.subscribers[this.subscribers.length] = コールバック;
}、
//購読を解除
removeSubscriber: 関数 (コールバック) {
for (var i = 0; i If (this.subscribers[i] === コールバック) {
delete (this.subscribers[i]);
}
}
}、
//公開
パブリッシュ: 関数 (何を) {
for (var i = 0; i If (typeof this.subscribers[i] === '関数') {
This.subscribers[i](何を);
}
}
}、
// オブジェクトにオブザーバー関数を持たせる
Make: function (o) {
for (var i in this) {
o[i] = this[i];
o.subscribers = [];
}
}
};

次に、blogger と user の 2 つのオブジェクトをサブスクライブし、observer.make メソッドを使用して、これら 2 つのオブジェクトにオブザーバー関数を持たせます。コードは次のとおりです。

コードをコピー コードは次のとおりです:

var blogger = {
推奨: function (id) {
var msg = 'dudu が推奨する投稿:' id;
This.publish(msg);
}
};

var user = {
投票: 関数 (id) {
var msg = '誰かが投票しました! ID=' id;
This.publish(msg);
}
};

オブザーバー.make(ブロガー);
オブザーバー.make(ユーザー);

使用方法は比較的簡単です。さまざまなコールバック関数をサブスクライブして、さまざまなオブザーバー オブジェクトに登録できます (同時に複数のオブザーバー オブジェクトに登録することもできます)。

コードをコピーします コードは次のとおりです:
var tom = {
読み取り: 関数 (何を) {
console.log('トムは次のメッセージを見ました: ' 何)
}
};

var mm = {
show: 関数 (何を) {
console.log('mm は次の情報を確認しました: ' 何を)
}
};
// 購読
blogger.addSubscriber(tom.read);
blogger.addSubscriber(mm.show);
blogger.recommend(123); //公開するために呼び出します

//購読を解除
blogger.removeSubscriber(mm.show);
blogger.recommend(456); //公開するために呼び出します

//別のオブジェクトのサブスクリプション
user.addSubscriber(mm.show);
user.vote(789); //公開を呼び出します

jQuery バージョン

jQuery バージョン 1.7 の新しいオン/オフ関数に従って、jQuery バージョンのオブザーバーを定義することもできます。


コードをコピー コードは次のとおりです:
(関数 ($) {

var o = $({});

$.subscribe = function () {
o.on.apply(o, 引数);
};

$.unsubscribe = function () {
o.off.apply(o, 引数);
};

$.publish = function () {
o.trigger.apply(o, 引数);
};

} (jQuery));

呼び出しメソッドは、上記の 3 つのバージョンよりも単純です:

コードをコピーします コードは次のとおりです:
//コールバック関数
関数ハンドル(e, a, b, c) {
// `e` はイベントオブジェクトなので注意する必要はありません
console.log(a b c);
};

//購読
$.subscribe("/some/topic", ハンドル);
//公開
$.publish("/some/topic", ["a", "b", "c"]) // 出力 abc


$.unsubscribe("/some/topic", handle) // 購読解除
;
//購読
$.subscribe("/some/topic", function (e, a, b, c) {
console.log(a b c);
});

$.publish("/some/topic", ["a", "b", "c"]) // 出力 abc

//Unsubscribe (unsubscribe ではコールバック関数の代わりに /some/topic 名が使用されます。これはバージョン 1 の例とは異なります
$.unsubscribe("/some/topic");

ご覧のとおり、彼のサブスクリプションとサブスクリプション解除ではコールバック関数名の代わりに文字列名が使用されているため、匿名関数が渡された場合でもサブスクリプションを解除できます。

概要

オブザーバーの使用例は次のとおりです。1 つのオブジェクトを変更するときに他のオブジェクトも同時に変更する必要があり、変更する必要があるオブジェクトの数が不明な場合は、オブザーバー パターンの使用を検討する必要があります。

一般に、オブザーバー パターンが行うことは分離であり、結合の両当事者が具体性ではなく抽象化に依存するようになります。そのため、それぞれの側での変更がもう一方の側の変更に影響を与えません。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
JavaScriptの進化:現在の傾向と将来の見通しJavaScriptの進化:現在の傾向と将来の見通しApr 10, 2025 am 09:33 AM

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

javascriptの分解:それが何をするのか、なぜそれが重要なのかjavascriptの分解:それが何をするのか、なぜそれが重要なのかApr 09, 2025 am 12:07 AM

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

pythonまたはjavascriptの方がいいですか?pythonまたはjavascriptの方がいいですか?Apr 06, 2025 am 12:14 AM

Pythonはデータサイエンスや機械学習により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、簡潔な構文とリッチライブラリエコシステムで知られており、データ分析とWeb開発に適しています。 2。JavaScriptは、フロントエンド開発の中核です。 node.jsはサーバー側のプログラミングをサポートしており、フルスタック開発に適しています。

JavaScriptをインストールするにはどうすればよいですか?JavaScriptをインストールするにはどうすればよいですか?Apr 05, 2025 am 12:16 AM

JavaScriptは、最新のブラウザにすでに組み込まれているため、インストールを必要としません。開始するには、テキストエディターとブラウザのみが必要です。 1)ブラウザ環境では、タグを介してHTMLファイルを埋め込んで実行します。 2)node.js環境では、node.jsをダウンロードしてインストールした後、コマンドラインを介してJavaScriptファイルを実行します。

クォーツでタスクが開始される前に通知を送信する方法は?クォーツでタスクが開始される前に通知を送信する方法は?Apr 04, 2025 pm 09:24 PM

Quartzタイマーを使用してタスクをスケジュールする場合、Quartzでタスク通知を事前に送信する方法、タスクの実行時間はCron式によって設定されます。今...

JavaScriptでは、コンストラクターのプロトタイプチェーンで関数のパラメーターを取得する方法は?JavaScriptでは、コンストラクターのプロトタイプチェーンで関数のパラメーターを取得する方法は?Apr 04, 2025 pm 09:21 PM

JavaScriptプログラミング、プロトタイプチェーンの関数パラメーターの理解と操作のJavaScriptのプロトタイプチェーンの関数のパラメーターを取得する方法は、一般的で重要なタスクです...

WeChat MiniプログラムWebViewでVUE.JSダイナミックスタイルの変位が失敗した理由は何ですか?WeChat MiniプログラムWebViewでVUE.JSダイナミックスタイルの変位が失敗した理由は何ですか?Apr 04, 2025 pm 09:18 PM

WeChatアプレットWeb-ViewでVue.jsを使用する動的スタイルの変位障害がvue.jsを使用している理由の分析...

TamperMonkeyで複数のリンクの同時GETリクエストを実装し、順番に戻る結果を決定する方法は?TamperMonkeyで複数のリンクの同時GETリクエストを実装し、順番に戻る結果を決定する方法は?Apr 04, 2025 pm 09:15 PM

複数のリンクの同時ゲットリクエストを作成し、結果を返すために順番に判断する方法は? TamperMonkeyスクリプトでは、複数のチェーンを使用する必要があることがよくあります...

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい