يقدم
يسمى وضع المراقب أيضًا النشر/الاشتراك. إنه يحدد علاقة واحدة إلى رواية ، مما يتيح لكائنات مراقب متعددة الاستماع إلى كائن موضوع في نفس الوقت. عندما تتغير حالة كائن الموضوع هذا ، سيتم إخطار جميع كائنات المراقب ، حتى يتمكنوا من تحديث أنفسهم تلقائيًا.
فوائد استخدام وضع المراقب:
1. يدعم اتصال البث البسيط ويبلغ جميع الكائنات المشتركة تلقائيًا.
2. بعد تحميل الصفحة ، يمكن أن يكون للكائن الهدف بسهولة ارتباط ديناميكي مع المراقب ، مما يزيد من المرونة.
3. يمكن توسيع علاقة الاقتران المجردة بين الكائن المستهدف والمراقب وإعادة استخدامها بشكل منفصل.
النص (الإصدار 1)
يتم تحقيق تنفيذ نمط المراقب في JS من خلال عمليات الاسترجاعات. دعنا أولاً نحدد كائن PubSub ، الذي يحتوي على 3 طرق: الاشتراك ، إلغاء الاشتراك ، والنشر.
نسخة الكود كما يلي:
var pubSub = {} ؛
(وظيفة (س) {
مواضيع var = {} ، // صفيف مخزنة بواسطة وظيفة رد الاتصال
subuid = -1 ؛
// method method
Q.Publish = function (topic ، args) {
إذا (! موضوعات [الموضوع]) {
العودة كاذبة
}
setTimeout (function () {
var المشتركين = الموضوعات [الموضوع] ،
لين = المشتركين؟ المشتركين. الطول: 0 ؛
بينما (لين-) {
المشتركين [Len] .func (الموضوع ، args) ؛
}
} ، 0) ؛
العودة صحيح.
} ؛
// طريقة الاشتراك
Q.Subscribe = function (topic ، func) {
إذا (! موضوعات [الموضوع]) {
موضوعات [الموضوع] = [] ؛
}
var token = (++ subuid) .toString () ؛
موضوعات [الموضوع] .push ({
الرمز المميز: رمز ،
FUNC: FUNC
}) ؛
الرمز الرمز المميز.
} ؛
// طريقة إلغاء الاشتراك
Q.UNSUBSCRICK = دالة (رمز) {
لـ (var m في الموضوعات) {
إذا (الموضوعات [M]) {
لـ (var i = 0 ، j = موضوعات [m] .length ؛ i <j ؛ i ++) {
if (موضوعات [m] [i]. token === token) {
موضوعات [m] .Splice (i ، 1) ؛
الرمز الرمز المميز.
}
}
}
}
العودة كاذبة
} ؛
} (pubSub)) ؛
كيفية استخدامه على النحو التالي:
نسخة الكود كما يلي:
// تعال ، اشترك في واحد
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'}]) ؛
ماذا عن ذلك؟ أليس من الجيد الاستخدام؟ ولكن هناك مشكلة في هذه الطريقة ، أي أنه لا توجد طريقة لإلغاء الاشتراك. إذا كنت ترغب في إلغاء الاشتراك ، فيجب عليك تحديد اسم إلغاء الاشتراك ، لذلك دعنا نذهب إلى إصدار آخر:
نسخة الكود كما يلي:
// تعيين الاشتراك لمتغير لإلغاء الاشتراك
var testSubscription = pubsub.subscribe ('example1' ، function (thision ، data) {
console.log (موضوعات + ":" + بيانات) ؛
}) ؛
// إشعار الإصدار
pubSub.publish ('example1' ، 'hello world!') ؛
pubSub.publish ('example1' ، ['test' ، 'a' ، 'b' ، 'c']) ؛
pubSub.publish ('example1' ، [{'color': 'Blue'} ، {'text': 'hello'}]) ؛
// unsubscription
setTimeout (function () {
pubSub.unsubscribe (TestSubscription) ؛
} ، 0) ؛
// نشر مرة أخرى للتحقق مما إذا كان لا يزال من الممكن إخراج المعلومات
pubSub.publish ('example1' ، 'hello مرة أخرى! (سوف يفشل هذا)') ؛
الإصدار 2
يمكننا أيضًا استخدام خصائص النموذج الأولي لتنفيذ نمط مراقب ، والرمز هو كما يلي:
نسخة الكود كما يلي:
وظيفة المراقب () {
this.fns = [] ؛
}
Observer.prototype = {
الاشتراك: وظيفة (fn) {
this.fns.push (fn) ؛
} ،
إلغاء الاشتراك: وظيفة (fn) {
this.fns = this.fns.filter (
وظيفة (el) {
إذا (el! == fn) {
إرجاع EL ؛
}
}
) ؛
} ،
تحديث: الدالة (o ، thisobj) {
var scope = thisobj || نافذة
this.fns.foreach (
وظيفة (el) {
el.call (Scope ، O) ؛
}
) ؛
}
} ؛
//امتحان
var o = مراقب جديد ؛
var f1 = function (data) {
console.log ('Robbin:' + data + '، العمل بسرعة!') ؛
} ؛
var f2 = function (data) {
console.log ('Randall:' + data + '، ابحث عنه للحصول على بعض الرواتب الإضافية!') ؛
} ؛
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) {
var scope = thisobj || نافذة
لـ (var i = 0 ، j = this.length ؛ i <j ؛ ++ i) {
fn.call (النطاق ، هذا [i] ، أنا ، هذا) ؛
}
} ؛
}
if (! array.prototype.filter) {
Array.Prototype.Filter = function (fn ، thisobj) {
var scope = thisobj || نافذة
var a = [] ؛
لـ (var i = 0 ، j = this.length ؛ i <j ؛ ++ i) {
إذا (! fn.call (النطاق ، هذا [i] ، أنا ، هذا)) {
يكمل؛
}
A.Push (هذا [i]) ؛
}
إرجاع أ ؛
} ؛
}
الإصدار 3
إذا كنت تريد أن يكون لدى كائنات متعددة وظيفة اشتراك نشر المراقب ، فيمكننا تحديد وظيفة مشتركة ثم تطبيق وظيفة الوظيفة على الكائن الذي يتطلب وظيفة المراقب. الرمز كما يلي:
نسخة الكود كما يلي:
// رمز عالمي
var observer = {
// الاشتراك
AddSubscriber: Function (Callback) {
this.subscribers [this.subscribers.length] = callback ؛
} ،
// unsubscription
إزالة ubsubscriber: وظيفة (رد الاتصال) {
لـ (var i = 0 ؛ i <this.subscribers.length ؛ i ++) {
if (this.subscribers [i] === callback) {
حذف (this.subscribers [i]) ؛
}
}
} ،
//يطلق
نشر: وظيفة (ماذا) {
لـ (var i = 0 ؛ i <this.subscribers.length ؛ i ++) {
if (typeof this.subscribers [i] === 'function') {
this.subscribers [i] (ماذا) ؛
}
}
} ،
// اجعل الكائن O لديك وظيفة مراقب
جعل: وظيفة (س) {
لـ (var i in this) {
o [i] = هذا [i] ؛
O.Subscribers = [] ؛
}
}
} ؛
ثم اشترك في مدون 2 كائنات ومستخدم ، استخدم طريقة المراقب.
نسخة الكود كما يلي:
var blogger = {
التوصية: وظيفة (معرف) {
var msg = 'dudu الموصى بها post:' + id ؛
this.publish (msg) ؛
}
} ؛
var user = {
التصويت: وظيفة (معرف) {
var msg = 'شخص ما صوت! id =' + id ؛
this.publish (msg) ؛
}
} ؛
Observer.make (Blogger) ؛
Observer.make (المستخدم) ؛
طريقة الاستخدام بسيطة نسبيا. اشترك في وظائف رد الاتصال المختلفة بحيث يمكنك التسجيل مع كائنات مراقب مختلفة (أو يمكن تسجيل كائنات مراقب متعددة في نفس الوقت):
نسخة الكود كما يلي:
فار توم = {
اقرأ: وظيفة (ماذا) {
console.log ('شاهد توم الرسالة التالية:' + ماذا)
}
} ؛
var mm = {
عرض: وظيفة (ماذا) {
console.log ('MM رأى الرسالة التالية:' + ماذا)
}
} ؛
// يشترك
blogger.addsubscriber (tom.read) ؛
blogger.addsubscriber (mm.show) ؛
Blogger.Recmond (123) ؛ // Call Publish
// unsubscription
blogger.removesubscriber (mm.show) ؛
blogger.Recmond (456) ؛ // Call Publish
// اشترك في كائن آخر
user.addsubscriber (mm.show) ؛
user.vote (789) ؛ // Call Publish
نسخة jQuery
وفقًا لوظيفة ON/OFF المضافة في الإصدار 1.7 jQuery ، يمكننا أيضًا تحديد مراقب إصدار jQuery:
نسخة الكود كما يلي:
(وظيفة ($) {
var o = $ ({}) ؛
$ .subscribe = function () {
o.on.apply (o ، الحجج) ؛
} ؛
$. unsubscribe = function () {
o.off.apply (o ، الحجج) ؛
} ؛
$ .publish = function () {
o.trigger.apply (o ، الحجج) ؛
} ؛
} (jQuery)) ؛
طريقة الاتصال أبسط من الإصدارات الثلاثة أعلاه:
نسخة الكود كما يلي:
// وظيفة رد الاتصال
مقبض الوظيفة (E ، A ، B ، C) {
// `e` هو كائن حدث ، لا يلزم الاهتمام
console.log (a + b + c) ؛
} ؛
// الاشتراك
دولار.
//يطلق
$ .publish ("/some/topic" ، ["A" ، "B" ، "C"]) ؛ // الإخراج ABC
دولار. // إلغاء الاشتراك
// الاشتراك
دولار.
console.log (a + b + c) ؛
}) ؛
$ .publish ("/some/topic" ، ["A" ، "B" ، "C"]) ؛ // الإخراج ABC
// unsubscribe (يستخدم Unsbscribe اسم/some/topic ، وليس وظيفة رد الاتصال ، والتي تختلف عن مثال الإصدار 1
$. unsubscribe ("/some/topic") ؛
يمكن ملاحظة أن اشتراكه وإلغاء الاشتراك في استخدام أسماء السلسلة ، وليس أسماء وظائف رد الاتصال ، لذلك حتى لو تم تمرير الوظيفة المجهولة الواردة ، فيمكننا إلغاء الاشتراك.
لخص
استخدام المراقبين هو: عندما يتغير كائن لتغيير الكائنات الأخرى في نفس الوقت ولا يعرف عدد الكائنات التي يجب تغييرها ، يجب أن تفكر في استخدام وضع المراقب.
بشكل عام ، فإن ما يفعله نمط المراقب هو فصله ، مما يجعل كلا جانبي الاقتران يعتمد على التجريد بدلاً من الخرسانة. هذا يجعل من الممكن أن تؤثر التغييرات في بعضها البعض على التغييرات على الجانب الآخر.