Rumah  >  Artikel  >  hujung hadapan web  >  Contoh pelaksanaan berbilang corak reka bentuk Javascript Kemahiran pattern_javascript pemerhati

Contoh pelaksanaan berbilang corak reka bentuk Javascript Kemahiran pattern_javascript pemerhati

WBOY
WBOYasal
2016-05-16 16:11:22781semak imbas

Pengenalan

Mod pemerhati juga dipanggil mod terbitkan/langgan (Terbitkan/Langganan Ia mentakrifkan perhubungan satu-ke-banyak, membenarkan berbilang objek pemerhati memantau objek topik tertentu pada masa yang sama perubahan objek topik, Semua objek pemerhati akan dimaklumkan supaya mereka boleh mengemas kini sendiri secara automatik.

Faedah menggunakan corak pemerhati:

1. Menyokong komunikasi penyiaran mudah dan memberitahu semua objek yang dilanggan secara automatik.
2. Selepas halaman dimuatkan, objek sasaran dengan mudah boleh mempunyai hubungan dinamik dengan pemerhati, yang meningkatkan fleksibiliti.
3. Hubungan gandingan abstrak antara objek sasaran dan pemerhati boleh dilanjutkan dan digunakan semula secara bebas.

Teks (versi 1)

Pelaksanaan corak pemerhati dalam JS dicapai melalui panggilan balik Mari kita tentukan objek pubsub, yang mengandungi 3 kaedah: langgan, nyahlanggan dan terbitkan.

Salin kod Kod adalah seperti berikut:

var pubsub = {};
(fungsi (q) {

var topics = {}, // Tatasusunan disimpan dalam fungsi panggil balik
        subUid = -1;
//Kaedah terbitan
​ q.publish = fungsi (topik, hujah) {

           jika (!topik[topik]) {
              pulangan palsu;
}

setTimeout(fungsi () {
               var pelanggan = topik[topik],
                len = pelanggan ?
              manakala (len--) {
                  pelanggan[len].func(topik, args);
            }
         }, 0);

        kembali benar;

};
//Kaedah langganan
​ q.langgan = fungsi (topik, func) {

           jika (!topik[topik]) {
topik[topik] = [];
}

      var token = ( subUid).toString();
topik[topik].tolak({
token: token,
               fungsi: func
        });
         token pulangan;
};
//Cara berhenti melanggan
​ q.berhenti melanggan = fungsi (token) {
untuk (var m dalam topik) {
                 jika (topik[m]) {
untuk (var i = 0, j = topik[m].panjang; i < j; i ) {
Jika (topik[m][i].token === token) {
topik[m].splice(i, 1);
                                        token pulangan;
                 }
                }
            }
}
         kembali palsu;
};
} (pubsub));

Gunakan seperti berikut:

Salin kod Kod adalah seperti berikut:

//Datang dan langgan
pubsub.subscribe('contoh1', fungsi (topik, data) {
console.log(topik ": " data);
});

//Terbitkan pemberitahuan
pubsub.publish('example1', 'hello world!');
pubsub.publish('example1', ['test', 'a', 'b', 'c']);
pubsub.publish('example1', [{ 'color': 'blue' }, { 'text': 'hello'}]);

Bagaimana pula? Bukankah ia bagus untuk digunakan? Tetapi terdapat masalah dengan kaedah ini, iaitu, tiada cara untuk berhenti melanggan. Jika anda ingin berhenti melanggan, anda mesti menyatakan nama penyahlangganan, jadi mari buat versi lain:

Salin kod Kod adalah seperti berikut:

//Tugaskan langganan kepada pembolehubah untuk berhenti melanggan
var testSubscription = pubsub.subscribe('example1', fungsi (topik, data) {
console.log(topik ": " data);
});

//Terbitkan pemberitahuan
pubsub.publish('example1', 'hello world!');
pubsub.publish('example1', ['test', 'a', 'b', 'c']);
pubsub.publish('example1', [{ 'color': 'blue' }, { 'text': 'hello'}]);

//Nyahlanggan
setTimeout(fungsi () {
pubsub.unsubscribe(testSubscription);
}, 0);

//Terbitkan sekali lagi untuk mengesahkan sama ada maklumat masih boleh dikeluarkan
pubsub.publish('example1', 'hello again! (ini akan gagal)');

Versi 2

Kita juga boleh menggunakan ciri-ciri prototaip untuk melaksanakan corak pemerhati Kodnya adalah seperti berikut:

Salin kod Kod adalah seperti berikut:

fungsi Pemerhati() {
This.fns = [];
}
Observer.prototype = {
Langgan: fungsi (fn) {
This.fns.push(fn);
},
berhenti melanggan: fungsi (fn) {
This.fns = this.fns.filter(
                               fungsi (el) {
Jika (el !== fn) {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        );
},
Kemas kini: fungsi (o, thisObj) {
        var skop = thisObj || This.fns.forEach(
                               fungsi (el) {
                           el.call(skop, o);
                                                                                                                                                          );
}
};

//Ujian
var o = Pemerhati baharu;
var f1 = fungsi (data) {
console.log('Robbin: ' data ', mula bekerja dengan cepat!');
};

var f2 = fungsi (data) {
console.log('Randall: ' data ', minta dia naikkan gaji!');
};

o.langgan(f1);
o.langgan(f2);

o.update("Tom sudah kembali!")

//Nyahlanggan f1
o.nyahlanggan(f1);
//Sahkan lagi
o.update("Tom sudah kembali!");

Jika anda digesa bahawa penapis atau untukSetiap fungsi tidak ditemui, ini mungkin kerana penyemak imbas anda tidak cukup baharu dan pada masa ini tidak menyokong fungsi standard baharu Anda boleh mentakrifkannya sendiri menggunakan kaedah berikut:

Salin kod Kod adalah seperti berikut:

jika (!Array.prototype.forEach) {
Array.prototype.forEach = fungsi (fn, thisObj) {
        var skop = thisObj || untuk (var i = 0, j = this.length; i < j; i) {
                   fn.panggilan(skop, ini[i], i, ini);
}
};
}
jika (!Array.prototype.filter) {
Array.prototype.filter = fungsi (fn, thisObj) {
        var skop = thisObj ||       var a = [];
untuk (var i = 0, j = this.length; i < j; i) {
Jika (!fn.call(skop, ini[i], i, ini)) {
                         teruskan;
            }
            a.push(ini[i]);
}
         kembalikan a;
};
}


Versi 3

Jika kita mahu berbilang objek supaya pemerhati menerbitkan dan melanggan fungsi, kita boleh mentakrifkan fungsi umum, dan kemudian menggunakan fungsi fungsi ini pada objek yang memerlukan fungsi pemerhati Kodnya adalah seperti berikut:

//Kod am
var pemerhati = {
//Langgan
TambahSubscriber: fungsi (panggilan balik) {
This.subscribers[this.subscribers.length] = panggil balik;
},
//Nyahlanggan
​ removeSubscriber: function (panggilan balik) {
untuk (var i = 0; i < this.subscribers.length; i ) {
Jika (pelanggan [i] ini === panggil balik) {
                    padam (ini.pelanggan[i]);
            }
}
},
//Terbitkan
terbitkan: fungsi (apa) {
untuk (var i = 0; i < this.subscribers.length; i ) {
Jika (jenis ini.pelanggan[i] === 'fungsi') {
This.subscribers[i](what);
            }
}
},
// Jadikan objek o mempunyai fungsi pemerhati
Jadikan: fungsi (o) {
untuk (var i dalam ini) {
            o[i] = ini[i];
               o.pelanggan = [];
}
}
};


Kemudian langgan dua objek blogger dan pengguna, dan gunakan kaedah observer.make untuk menjadikan kedua-dua objek ini mempunyai fungsi pemerhati Kodnya adalah seperti berikut:

Salin kod Kod adalah seperti berikut:

var blogger = {
Syorkan: fungsi (id) {
        var msg = 'Catatan disyorkan oleh dudu:' id;
This.publish(msg);
}
};

pengguna var = {
undi: fungsi (id) {
        var msg = 'Seseorang mengundi ID=' id;
This.publish(msg);
}
};

observer.make(blogger);
observer.make(user);

Kaedah penggunaan agak mudah Langgan fungsi panggil balik yang berbeza supaya anda boleh mendaftar ke objek pemerhati yang berbeza (anda juga boleh mendaftar ke berbilang objek pemerhati pada masa yang sama):

Salin kod Kod adalah seperti berikut:

var tom = {
Baca: fungsi (apa) {
console.log('Tom melihat mesej berikut: ' apa)
}
};

var mm = {
tunjukkan: fungsi (apa) {
console.log('mm melihat maklumat berikut: ' apa)
}
};
// Langgan
blogger.addSubscriber(tom.read);
blogger.addSubscriber(mm.show);
blogger.recommend(123); //Panggil untuk menerbitkan

//Nyahlanggan
blogger.removeSubscriber(mm.show);
blogger.recommend(456); //Panggil untuk menerbitkan

//Langganan objek lain
user.addSubscriber(mm.show);
user.vote(789); //Panggil terbitkan

versi jQuery

Menurut fungsi hidup/mati baharu jQuery versi 1.7, kami juga boleh mentakrifkan versi pemerhati jQuery:

Salin kod Kod adalah seperti berikut:

(fungsi ($) {

var o = $({});

$.langgan = fungsi () {
o.on.apply(o, arguments);
};

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

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

} (jQuery));

Kaedah panggilan adalah lebih mudah daripada tiga versi di atas:

Salin kod Kod adalah seperti berikut:

//Fungsi panggil balik
pemegang fungsi(e, a, b, c) {
// `e` ialah objek acara, tidak perlu diberi perhatian
console.log(a b c);
};

//Langgan
$.subscribe("/some/topic", handle);
//Terbitkan
$.publish("/some/topic", ["a", "b", "c"]); // Output abc
                             

$.unsubscribe("/some/topic", handle); // Nyahlanggan

//Langgan
$.subscribe("/some/topic", fungsi (e, a, b, c) {
console.log(a b c);
});

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

//Nyahlanggan (nyahlanggan menggunakan nama /some/topic dan bukannya fungsi panggil balik, yang berbeza daripada contoh dalam versi 1
$.unsubscribe("/some/topic");

Seperti yang anda lihat, langganan dan penyahlangganannya menggunakan nama rentetan dan bukannya nama fungsi panggil balik, jadi walaupun fungsi tanpa nama dihantar, kami masih boleh menyahlanggan.

Ringkasan

Kes penggunaan pemerhati ialah: apabila perubahan pada satu objek memerlukan perubahan pada objek lain pada masa yang sama, dan ia tidak tahu berapa banyak objek yang perlu ditukar, anda harus mempertimbangkan untuk menggunakan corak pemerhati.

Secara umum, apa yang dilakukan oleh corak pemerhati ialah penyahgandingan, menjadikan kedua-dua pihak gandingan bergantung pada pengabstrakan dan bukannya kekonkretan. Supaya perubahan pada setiap pihak tidak akan mempengaruhi perubahan di pihak yang lain.

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn