memperkenalkan
Mode jembatan memisahkan bagian -bagian abstrak dari bagian implementasinya sehingga semuanya dapat bervariasi secara mandiri.
teks
Mode jembatan paling umum digunakan dalam pemantauan acara. Pertama -tama mari kita lihat sepotong kode:
Salinan kode adalah sebagai berikut:
addEvent (elemen, 'klik', getBeerById);
function getBeerById (e) {
var id = this.id;
asyncRequest ('get', 'beer.uri? id =' + id, function (resp) {
// Tanggapan panggilan balik.
console.log ('Bir yang diminta:' + resp.Responsetext);
});
}
Ada masalah dengan kode di atas bahwa GetBeerById harus memiliki konteks browser untuk digunakan, karena menggunakan ini. Properti ID secara internal. Jika konteksnya tidak digunakan, maka itu akan berhenti. Oleh karena itu, umumnya seorang programmer yang sedikit berpengalaman akan mengubah program menjadi bentuk berikut:
Salinan kode adalah sebagai berikut:
function getBeerById (id, callback) {
// Kirim permintaan melalui ID dan kembalikan data
asyncRequest ('get', 'beer.uri? id =' + id, function (resp) {
// Tanggapan panggilan balik
callback (resp.Responsetext);
});
}
Lebih praktis, bukan? Pertama, ID dapat dilewati sesuka hati, dan fungsi panggilan balik juga disediakan untuk fungsi pemrosesan khusus. Tapi apa hubungannya ini dengan menjembatani? Inilah yang akan dicerminkan oleh kode berikut:
Salinan kode adalah sebagai berikut:
addEvent (elemen, 'klik', getBeerbyidbridge);
Fungsi getBeerByidBridge (e) {
getBeerById (this.id, function (bir) {
Console.log ('Bir yang Diminta:'+Bir);
});
}
Di sini, GetBeerByidBridge adalah jembatan yang kami definisikan, yang digunakan untuk menghubungkan acara klik abstrak dan getBeerById, dan pada saat yang sama melewati ID dari sumber acara dan fungsi panggilan yang disesuaikan (output Console.log) ke dalam fungsi GetBeerById sebagai parameter.
Contoh ini terlihat agak sederhana, mari kita ambil contoh praktis lain yang lebih rumit.
Antrian koneksi XHR yang sebenarnya
Kami ingin membangun antrian, yang menyimpan banyak permintaan AJAX dalam antrian. Penggunaan antrian terutama karena kita perlu memastikan bahwa permintaan yang bergabung diproses terlebih dahulu. Kapan saja, kami dapat menjeda permintaan, menghapus permintaan, mencoba lagi permintaan, dan mendukung acara berlangganan untuk setiap permintaan.
Fungsi inti dasar
Sebelum dimulai resmi, mari kita tentukan beberapa fungsi enkapsulasi inti. Pertama, yang pertama adalah enkapsulasi fungsi dari permintaan asinkron:
Salinan kode adalah sebagai berikut:
var asyncrequest = (function () {
function handlereadystate (o, callback) {
var poll = window.setInterval (
fungsi () {
if (o && o.readystate == 4) {
window.clearinterval (jajak pendapat);
if (callback) {
callback (o);
}
}
},
50
);
}
var getxhr = function () {
var http;
mencoba {
http = xmlhttpRequest baru;
getxhr = function () {
mengembalikan XmlHttpRequest baru;
};
}
Catch (e) {
var msxml = [
'Msxml2.xmlhttp.3.0',
'Msxml2.xmlhttp',
'Microsoft.xmlhttp'
];
untuk (var i = 0, len = msxml.length; i <len; ++ i) {
mencoba {
http = ActivexObject baru (msxml [i]);
getxhr = function () {
return new ActiveXObject (msxml [i]);
};
merusak;
}
catch (e) {}
}
}
mengembalikan http;
};
Fungsi Pengembalian (Metode, URI, Callback, PostData) {
var http = getXhr ();
http.open (metode, uri, true);
handlereadystate (http, callback);
http.send (postdata || null);
mengembalikan http;
};
}) ();
Fungsi pengukuhan diri yang dienkapsulasi adalah fungsi permintaan AJAX umum, dan saya percaya bahwa siapa pun dengan atribut AJAX dapat memahaminya.
Selanjutnya kami mendefinisikan metode umum untuk menambahkan metode (fungsi):
Salinan kode adalah sebagai berikut:
Function.prototype.method = function (name, fn) {
this.prototype [name] = fn;
kembalikan ini;
};
Akhirnya, tambahkan 2 metode tentang array, satu untuk traversal dan satu untuk penyaringan:
Salinan kode adalah sebagai berikut:
if (! array.prototype.foreach) {
Array.method ('foreach', function (fn, thisobj) {
var scope = thisobj || jendela;
untuk (var i = 0, len = this.length; i <len; ++ i) {
fn.call (lingkup, ini [i], i, ini);
}
});
}
if (! array.prototype.filter) {
Array.method ('filter', function (fn, thisobj) {
var scope = thisobj || jendela;
var a = [];
untuk (var i = 0, len = this.length; i <len; ++ i) {
if (! fn.call (lingkup, ini [i], i, this)) {
melanjutkan;
}
A.Push (ini [i]);
}
mengembalikan a;
});
}
Karena beberapa browser baru sudah mendukung dua fungsi ini (atau beberapa perpustakaan kelas sudah mendukung mereka), pertama -tama kita harus menilai jika mereka sudah didukung, dan jika mereka sudah didukung, mereka tidak akan lagi diproses.
Sistem pengamat
Pengamat memainkan peran penting dalam proses peristiwa dalam antrian dan dapat berlangganan peristiwa saat antri (keberhasilan, kegagalan, tertunda):
Salinan kode adalah sebagai berikut:
window.ded = window.ded || {};
Ded.util = ded.util || {};
Ded.util.observer = function () {
this.fns = [];
}
Ded.util.observer.prototype = {
Berlangganan: function (fn) {
this.fns.push (fn);
},
berhenti berlangganan: function (fn) {
this.fns = this.fns.filter (
function (el) {
if (el! == fn) {
mengembalikan el;
}
}
);
},
Fire: function (o) {
this.fns.foreach (
function (el) {
el (o);
}
);
}
};
Kode implementasi antrian utama
Pertama, Anda berlangganan atribut utama dan delegasi acara antrian:
Salinan kode adalah sebagai berikut:
Ded.queue = function () {
// berisi antrian untuk permintaan.
this.queue = [];
// Gunakan objek yang dapat diamati pada 3 status berbeda sehingga Anda dapat berlangganan acara kapan saja
this.onComplete = ded.util.observer baru;
this.onfailure = ded.util.observer baru;
this.onchush = ded.util.observer baru;
// Properti inti dapat diatur selama panggilan eksternal
this.retrycount = 3;
this.currentretry = 0;
this.paused = false;
this.timeout = 5000;
this.conn = {};
this.timer = {};
};
Kemudian, melalui panggilan rantai ded.queue.method, banyak metode yang tersedia ditambahkan ke antrian:
Salinan kode adalah sebagai berikut:
Ded.queue.
metode ('flush', function () {
// Metode flush
if (! this.queue.length> 0) {
kembali;
}
if (this.paused) {
this.paused = false;
kembali;
}
var itu = ini;
this.currentretry ++;
var abort = function () {
that.conn.abort ();
if (that.currentretry == that.retrycount) {
that.onfailure.fire ();
itu.currentretry = 0;
} kalau tidak {
that.flush ();
}
};
this.timer = window.setTimeout (abort, this.timeout);
var callback = function (o) {
window.cleartimeout (that.timer);
itu.currentretry = 0;
that.queue.shift ();
that.onflush.fire (O.Responsetext);
if (that.queue.length == 0) {
that.oncomplete.fire ();
kembali;
}
// panggilan rekursif untuk menyiram
that.flush ();
};
this.conn = asyncRequest (
this.queue [0] ['Metode'],
this.queue [0] ['uri'],
panggilan balik,
this.queue [0] ['params']
);
}).
metode ('setRetryCount', function (count) {
this.retrycount = count;
}).
metode ('setTimeout', function (time) {
this.timeout = waktu;
}).
metode ('add', function (o) {
this.queue.push (o);
}).
metode ('jeda', function () {
this.paused = true;
}).
metode ('dequeue', function () {
this.queue.pop ();
}).
metode ('clear', function () {
this.queue = [];
});
Kode terlihat banyak, dan setelah lipat, Anda dapat menemukan bahwa itu sebenarnya didefinisikan pada antrian dengan flush, setRetryCount, setTimeout, ADD, Jeda, Dequeue, dan metode yang jelas.
Panggilan sederhana
Salinan kode adalah sebagai berikut:
var q = ded.queue baru;
// Atur jumlah retry sedikit lebih tinggi untuk mengatasi koneksi lambat
Q.SetRetryCount (5);
// Tetapkan waktu batas waktu
Q.SetTimeout (1000);
// Tambahkan 2 permintaan.
Q.Add ({
Metode: 'dapatkan',
Uri: '/path/to/file.php?Ajax=True'
});
Q.Add ({
Metode: 'dapatkan',
Uri: '/path/to/file.php?Ajax=true&woe=me'
});
// siram antrian
Q.Flush ();
// Jeda antrian dan simpan yang tersisa
q.Pause ();
// Jernih.
q.clear ();
// Tambahkan 2 permintaan.
Q.Add ({
Metode: 'dapatkan',
Uri: '/path/to/file.php?Ajax=True'
});
Q.Add ({
Metode: 'dapatkan',
Uri: '/path/to/file.php?Ajax=true&woe=me'
});
// Hapus permintaan terakhir dari antrian.
q.dequeue ();
// siram lagi
Q.Flush ();
Dimana jembatannya?
Tidak ada jembatan dalam kode panggilan di atas, jadi bagaimana dengan jembatan? Lihatlah contoh lengkap di bawah ini dan Anda akan menemukan bahwa ada jembatan di mana -mana:
Salinan kode adalah sebagai berikut:
<! Doctype html public "-// w3c // dtd html 4.01 // en"
"http://www.w3.org/tr/html4/strict.dtd">
<Html>
<head>
<meta http-equiv = "konten tipe" content = "text/html; charset = utf-8">
<title> AJAX Connection Antrian </iteme>
<skrip src = "utils.js"> </script>
<skrip src = "queue.js"> </script>
<type skrip = "Teks/JavaScript">
addEvent (window, 'load', function () {
// menyelesaikan.
var q = ded.queue baru;
Q.SetRetryCount (5);
Q.SetTimeout (3000);
var item = $ ('item');
var hasil = $ ('hasil');
var Queue = $ ('Queue-items');
// Simpan lacak permintaan Anda di klien
var requests = [];
// Setelah setiap permintaan flush, berlangganan langkah pemrosesan khusus
q.Onflush.subscribe (function (data) {
results.innerhtml = data;
requests.shift ();
queue.innerhtml = requests.toString ();
});
// Langkah Pemrosesan Waktu Berlangganan
Q.onfailure.subscribe (function () {
hasil.
});
// Berlangganan semua langkah pemrosesan yang berhasil x
q.onComplete.subscribe (function () {
hasil.
});
var actionDispatcher = function (element) {
switch (elemen) {
kasus 'flush':
Q.Flush ();
merusak;
kasus 'dequeue':
q.dequeue ();
requests.pop ();
queue.innerhtml = requests.toString ();
merusak;
kasus 'jeda':
q.Pause ();
merusak;
kasus 'jelas':
q.clear ();
permintaan = [];
queue.innerhtml = '';
merusak;
}
};
var addRequest = function (request) {
var data = request.split ('-') [1];
Q.Add ({
Metode: 'dapatkan',
Uri: 'jembatan-koneksi-queue.php? Ajax = true & s =' + data,
Params: NULL
});
requests.push (data);
queue.innerhtml = requests.toString ();
};
addEvent (item, 'klik', fungsi (e) {
var e = e || window.event;
var src = e.target || E.Srcelement;
mencoba {
e.preventdefault ();
}
Catch (ex) {
E.ReturnValue = false;
}
ActionDispatcher (SRC.ID);
});
var adders = $ ('adders');
addEvent (adders, 'click', function (e) {
var e = e || window.event;
var src = e.target || E.Srcelement;
mencoba {
e.preventdefault ();
}
Catch (ex) {
E.ReturnValue = false;
}
addRequest (src.id);
});
});
</script>
<type style = "text/css" media = "screen">
Tubuh
{
Font: 100% Georgia, Times, Serif;
}
H1, H2
{
Font-Weight: Normal;
}
#antrian-item
{
Tinggi: 1.5em;
}
#add-suap
{
padding: .5em;
Latar belakang: #ddd;
Perbatasan: 1px solid #bbb;
}
#Hasil-area
{
padding: .5em;
Perbatasan: 1px solid #bbb;
}
</tyle>
</head>
<body id = "example">
<Div id = "doc">
<h1>
Permintaan gabungan asinkron </h1>
<div id = "antrian-item">
</div>
<Div id = "add-stuff">
<H2> Tambahkan permintaan baru ke antrian </h2>
<ul id = "adders">
<li> <a href = "#" id = "action-01"> Tambahkan "01" ke antrian </a> </li>
<li> <a href = "#" id = "action-02"> Tambahkan "02" ke antrian </a> </li>
<li> <a href = "#" id = "action-03"> Tambahkan "03" ke antrian </a> </li>
</ul>
</div>
<h2> Kontrol kutipan </h2>
<ul id = 'item'>
<li> <a href = "#" id = "flush"> flush </a> </li>
<li> <a href = "#" id = "dequeue"> Dequeue </a> </li>
<li> <a href = "#" id = "jeda"> jeda </a> </li>
<li> <a href = "#" id = "clear"> hapus </a> </li>
</ul>
<Div id = "hasil-area">
<h2>
hasil:
</h2>
<Div id = "hasil">
</div>
</div>
</div>
</body>
</html>
Dalam contoh ini, Anda dapat melakukan berbagai tindakan seperti antrian flush, jeda antrian, menghapus permintaan dalam antrian, antrian yang jelas, dll. Pada saat yang sama, saya percaya semua orang juga mengalami kekuatan jembatan.
Meringkaskan
Keuntungan dari mode jembatan juga jelas. Kami hanya akan mencantumkan beberapa keuntungan utama:
1. Pisahkan antarmuka dan bagian implementasi. Implementasi mungkin tidak terikat pada antarmuka selalu. Implementasi kelas abstrak (fungsi) dapat dikonfigurasi pada runtime, dan suatu objek bahkan dapat mengubah implementasinya saat runtime. Ini juga sepenuhnya memisahkan abstraksi dan implementasi, yang juga kondusif untuk pelapisan, sehingga menghasilkan sistem terstruktur yang lebih baik.
2. Tingkatkan skalabilitas
3. Rincian implementasi transparan untuk pelanggan dan dapat menyembunyikan detail implementasi dari pelanggan.
Pada saat yang sama, mode jembatan juga memiliki kerugiannya sendiri:
Sejumlah besar kelas akan menyebabkan peningkatan biaya pengembangan dan juga dapat mengurangi kinerja.