ใน JavaScript การเรียกใช้เมธอดแบบลูกโซ่เป็นที่นิยมอย่างมาก และเพื่อนที่ใช้ jQuery จะต้องมีความเข้าใจอย่างลึกซึ้งในเรื่องนี้ วิธีการนี้อธิบายไว้ในรายละเอียดเพิ่มเติมใน "รูปแบบการออกแบบ Javascript" หากต้องการใช้การเรียกเมธอดแบบลูกโซ่ คุณจะต้องปล่อยให้เมธอดที่กำหนดไว้ในต้นแบบส่งคืนการอ้างอิงไปยังออบเจ็กต์อินสแตนซ์ที่เรียกใช้เมธอดเหล่านี้ ลองดูในหนังสือ This รหัส:
(การทำงาน() {
ฟังก์ชั่น _$(els) {
นี้.องค์ประกอบ = [];
สำหรับ (var i = 0, len = els.length; i < len; ++i) {
องค์ประกอบ var = els [i];
ถ้า (องค์ประกอบ typeof == 'สตริง') {
องค์ประกอบ = document.getElementById (องค์ประกอบ);
-
this.elements.push(องค์ประกอบ);
-
-
_$.ต้นแบบ = {
แต่ละ: ฟังก์ชั่น (fn) {
สำหรับ ( var i = 0, len = this.elements.length; i < len; ++i ) {
fn.call(นี่, this.elements[i]);
-
คืนสิ่งนี้;
-
setStyle: ฟังก์ชั่น (เสา, วาล) {
this.each (ฟังก์ชั่น (el) {
el.style[prop] = วาล;
-
คืนสิ่งนี้;
-
แสดง: ฟังก์ชั่น () {
var นั่น = นี่;
this.each (ฟังก์ชั่น (el) {
that.setStyle('display', 'block');
-
คืนสิ่งนี้;
-
addEvent: ฟังก์ชั่น (ประเภท fn) {
var เพิ่ม = ฟังก์ชั่น (el) {
ถ้า (window.addEventListener) {
el.addEventListener(ชนิด, fn, เท็จ);
-
อื่นถ้า (window.attachEvent) {
el.attachEvent('บน'+ประเภท, fn);
-
-
this.each (ฟังก์ชั่น (el) {
เพิ่ม(เอล);
-
คืนสิ่งนี้;
-
-
หน้าต่าง.$ = ฟังก์ชั่น() {
ส่งคืนใหม่ _$ (อาร์กิวเมนต์);
-
-
อย่างที่คุณเห็น แต่ละเมธอดจะลงท้ายด้วย "return this" ซึ่งส่งอ็อบเจ็กต์ของเมธอดการเรียกไปยังเมธอดถัดไปในห่วงโซ่ อย่างไรก็ตาม หากข้อมูลที่เราต้องการดำเนินการได้รับผ่านการร้องขอแบบอะซิงโครนัส จะรักษาสายโซ่ของการเรียกเมธอดได้อย่างไร? Dustin Diaz ให้แนวทางแก่เราในการรับรองการเรียกเมธอดแบบลูกโซ่ เขายังเป็นหนึ่งในผู้เขียนหนังสือ "Javascript Design Patterns"
ขั้นแรกเขาสร้างวัตถุ Queue กล่าวคือ:
จากนั้นใช้เป็นเครื่องมือในการสร้างห่วงโซ่คิววิธีการแบบอะซิงโครนัสของเรา ด้วยเครื่องมือนี้ มันเป็นเรื่องง่ายที่จะสร้างปลั๊กอิน jQuery ที่ดึงเนื้อหาจากเซิร์ฟเวอร์และผนวกเข้ากับตัวเลือก
ด้วยวิธีนี้ เราสามารถรับเนื้อหาแบบอะซิงโครนัสและดำเนินการสายการโทรของเราต่อไปได้
$("<div/>")
.fetch('/server/navigation.html')
.addClass('คอลัมน์')
.appendTo('#side');
ตรวจสอบหน้า สาธิต เพื่อดูผลกระทบ
จะทำอย่างไรถ้ามีหลายรายการในคิวที่รอดำเนินการกับการตอบกลับฝั่งเซิร์ฟเวอร์? ผู้เขียนได้สร้างวิธีการดังกล่าวซึ่งควรค่าแก่การอ้างอิงถึง:
ด้วยวิธีนี้เราสามารถเรียกมันได้ดังต่อไปนี้:
fetchTweet(url).linkify().filterBadWords().appendTo('#status');
ณ จุดนี้ เรารู้แล้วว่าจะใช้วิธีผูกมัดวิธีการแบบอะซิงโครนัสได้อย่างไร แต่บางคำถามที่เกิดขึ้นจากความคิดเห็นบางส่วนที่ด้านล่างของ " การเชื่อมโยงคิววิธีอะซิงโครนัสใน JavaScript " เป็นสิ่งที่ควรค่าแก่การพิจารณา ปลั๊กอิน $.fn.fetch จำเป็นต้องผนวกเนื้อหาที่ส่งคืนเข้ากับองค์ประกอบเท่านั้น คิวจำเป็นหรือไม่ ยิ่งไปกว่านั้น $.fn.load ใน jQuery สามารถใช้งานได้อย่างสมบูรณ์ หากใช้ฟังก์ชัน Callback เพียงฟังก์ชันเดียวใน Queue ก็สามารถเขียนได้ดังนี้:
(ฟังก์ชั่น ($) {
$.fn.fetch = ฟังก์ชั่น (url) {
คิว var = คิวใหม่;
this.each (ฟังก์ชัน () {
var el = นี่;
$.ajax({
ที่อยู่: ที่อยู่,
ประเภท: 'รับ'
ประเภทข้อมูล: 'json',
ความสำเร็จ: ฟังก์ชั่น (ตอบสนอง) {
$(el).html(resp['text1']);
-
-
-
คืนสิ่งนี้;
-
})(เจเคอรี่);
ฉันสงสัยว่าคุณคิดอย่างไร?
ฟังก์ชั่น fetchTweet (url) {
this.queue = คิวใหม่;
this.twitter = "";
var self = นี่;
อาแจ็กซ์ (url, ฟังก์ชั่น (ตอบกลับ) {
self.twitter = ตอบกลับ;
self.queue.flush (สิ่งนี้);
-
-
fetchTweet.prototype = {
ลิงค์: ฟังก์ชั่น () {
this.queue.add (ฟังก์ชั่น (ตัวเอง) {
self.twitter = self.twitter.replace(/b@(w{1,20}b/g, '$1');
-
คืนสิ่งนี้;
-
filterBadWords: ฟังก์ชั่น () {
this.queue.add (ฟังก์ชั่น (ตัวเอง) {
self.twitter = self.twitter.replace(/b(แม่ง|อึ|ฉี่)b/g, "");
-
คืนสิ่งนี้;
-
ผนวกไปที่: ฟังก์ชั่น (ตัวเลือก) {
this.queue.add (ฟังก์ชั่น (ตัวเอง) {
$(self.twitter).appendTo(ตัวเลือก);
-
คืนสิ่งนี้;
-
-
(ฟังก์ชั่น ($) {
$.fn.fetch = ฟังก์ชั่น (url) {
var Queue = คิวใหม่;
this.each (ฟังก์ชัน () {
var el = นี่;
Queue.add (ฟังก์ชั่น (ตอบสนอง) {
$(el).html(ตอบกลับ);
-
-
$.ajax({
ที่อยู่: ที่อยู่,
ประเภทข้อมูล: 'html',
ความสำเร็จ: ฟังก์ชั่น (html) {
คิว.ฟลัช(html);
-
-
คืนสิ่งนี้;
-
})(เจเคอรี่);
คิวฟังก์ชัน () {
// เก็บการโทรกลับของคุณ
นี้._วิธีการ = [];
// เก็บการอ้างอิงถึงคำตอบของคุณ
this._response = null;
// คิวทั้งหมดเริ่มต้นแบบไม่ฟลัช
this._flush = เท็จ;
-
คิว.ต้นแบบ = {
// เพิ่มการโทรกลับในคิวของคุณ
เพิ่ม: ฟังก์ชั่น (fn) {
// หากคิวถูกล้างแล้ว ให้กลับมาทันที
ถ้า (this._flushed) {
fn(this._response);
// มิฉะนั้นให้ดันไปที่คิว
} อื่น {
นี้._methods.push(fn);
-
-
ล้าง: ฟังก์ชั่น (ตอบสนอง) {
// หมายเหตุ: การฟลัชจะเกิดขึ้นเพียงครั้งเดียวเท่านั้น
ถ้า (this._flushed) {
กลับ;
-
// เก็บการตอบกลับของคุณสำหรับการโทรครั้งต่อไปหลังจากล้าง ()
this._response = คำตอบ;
// ทำเครื่องหมายว่าถูกฟลัชแล้ว
นี้._flush = จริง;
// เลื่อนพวกมันออกไปแล้วโทรกลับ
ในขณะที่ (this._methods[0]) {
this._methods.shift()(ตอบ);
-
-
-