Dalam JavaScript , pemanggilan metode berantai sangat populer, dan teman-teman yang menggunakan jQuery harus memiliki pemahaman yang mendalam tentang hal ini. Metode ini dijelaskan secara lebih rinci dalam "Pola Desain Javascript". Untuk mengimplementasikan pemanggilan metode secara berantai, Anda hanya perlu membiarkan metode yang ditentukan dalam prototipe mengembalikan referensi ke objek instance yang memanggil metode ini kode:
(fungsi() {
fungsi _$(els) {
this.elements = [];
for (var i = 0, len = els.length; i < len; ++i) {
var elemen = els[i];
if (tipe elemen == 'string') {
elemen = dokumen.getElementById(elemen);
}
this.elements.push(elemen);
}
};
_$.prototipe = {
masing-masing: fungsi(fn) {
for ( var i = 0, len = this.elements.length; i < len; ++i ) {
fn.call(ini, ini.elemen[i]);
}
kembalikan ini;
},
setStyle: fungsi(prop, val) {
ini.setiap(fungsi(el) {
el.gaya[prop] = val;
});
kembalikan ini;
},
tampilkan: fungsi() {
var itu = ini;
ini.setiap(fungsi(el) {
itu.setStyle('tampilan', 'blok');
});
kembalikan ini;
},
addEvent: fungsi(tipe, fn) {
var tambahkan = fungsi(el) {
if (jendela.addEventListener) {
el.addEventListener(ketik, fn, salah);
}
else if (window.attachEvent) {
el.attachEvent('on'+type, fn);
}
};
ini.setiap(fungsi(el) {
tambahkan(el);
});
kembalikan ini;
}
};
jendela.$ = fungsi() {
kembalikan _$(argumen);
};
})();
Seperti yang Anda lihat, setiap metode diakhiri dengan "kembalikan ini", yang meneruskan objek metode pemanggil ke metode berikutnya dalam rantai. Namun, jika data yang ingin kita operasikan diperoleh melalui permintaan asinkron, bagaimana cara mempertahankan rangkaian pemanggilan metode? Dustin Diaz memberi kita cara untuk memastikan pemanggilan metode berantai. Dia juga salah satu penulis buku "Pola Desain Javascript".
Dia pertama kali membangun objek Antrian, yaitu:
Kemudian gunakan itu sebagai alat untuk membangun rantai antrian metode asinkron kita. Dengan alat ini, mudah untuk membuat plugin jQuery yang mengambil konten dari server dan menambahkannya ke pemilih.
Dengan cara ini, kami bisa mendapatkan konten secara asinkron dan melanjutkan rangkaian panggilan kami.
$("<div/>")
.fetch('/server/navigation.html')
.addClass('kolom')
.appendTo('#sisi');
Lihat halaman demo untuk melihat efeknya.
Apa yang harus dilakukan jika ada banyak item dalam antrian yang menunggu untuk ditindaklanjuti pada respons sisi server? Penulis membangun metode seperti itu, yang patut dirujuk:
Dengan cara ini, kita dapat menyebutnya sebagai berikut:
ambilTweet(url).linkify().filterBadWords().appendTo('#status');
Pada titik ini, kita sudah mengetahui cara mengimplementasikan rangkaian metode asinkron, namun beberapa pertanyaan yang diajukan oleh beberapa komentar di bagian bawah " Rangkaian antrian metode asinkron dalam JavaScript " patut untuk dipikirkan. Plug-in $.fn.fetch hanya perlu menambahkan konten yang dikembalikan ke elemen. Selain itu, $.fn.load di jQuery dapat diimplementasikan sepenuhnya jika hanya satu fungsi callback yang digunakan di Queue, maka dapat ditulis seperti ini:
(fungsi($) {
$.fn.mengambil = fungsi(url) {
var antrian = Antrian baru;
ini.setiap(fungsi() {
var el = ini;
$.ajax({
url: url,
ketik: 'dapatkan',
tipe data: 'json',
sukses: fungsi(resp) {
$(el).html(resp['teks1']);
}
});
});
kembalikan ini;
};
})(jQuery);
Saya ingin tahu apa yang Anda pikirkan?
fungsi mengambilTweet(url) {
this.queue = Antrian baru;
ini.tweet = "";
var diri = ini;
ajax(url, fungsi(resp) {
self.tweet = resp;
self.queue.flush(ini);
});
}
ambilTweet.prototipe = {
menghubungkan: fungsi() {
this.queue.add(fungsi(mandiri) {
self.tweet = self.tweet.replace(/b@(w{1,20}b/g, '$1');
});
kembalikan ini;
},
filterKata Buruk: fungsi() {
this.queue.add(fungsi(mandiri) {
self.tweet = self.tweet.replace(/b(fuck|shit|piss)b/g, "");
});
kembalikan ini;
},
appendTo: fungsi(pemilih) {
this.queue.add(fungsi(mandiri) {
$(self.tweet).appendTo(selector);
});
kembalikan ini;
}
};
(fungsi($) {
$.fn.mengambil = fungsi(url) {
var antrian = Antrian baru;
ini.setiap(fungsi() {
var el = ini;
antrian.tambahkan(fungsi(resp) {
$(el).html(resp);
});
});
$.ajax({
url: url,
tipe data: 'html',
sukses: fungsi(html) {
antrian.flush(html);
}
});
kembalikan ini;
};
})(jQuery);
fungsi Antrian() {
// simpan panggilan balik Anda
ini._metode = [];
// simpan referensi untuk tanggapan Anda
this._response = null;
// semua antrian dimulai tanpa diflush
this._flushed = salah;
}
Antrian.prototipe = {
// menambahkan callback ke antrean Anda
tambahkan: fungsi(fn) {
// jika antrian sudah terhapus, segera kembali
jika (ini._flushed) {
fn(ini._response);
// jika tidak, dorong ke antrian
} kalau tidak {
this._methods.push(fn);
}
},
siram: fungsi(resp) {
// catatan: flush hanya terjadi sekali
jika (ini._flushed) {
kembali;
}
// simpan respons Anda untuk panggilan berikutnya setelah flush()
this._response = resp;
// tandai bahwa sudah di-flush
this._flushed = benar;
// keluarkan mereka dan panggil mereka kembali
while (ini._metode[0]) {
this._methods.shift()(resp);
}
}
};