การโทรกลับถูกกำหนดใน Wikipedia เป็น:
ในการเขียนโปรแกรมคอมพิวเตอร์ฟังก์ชั่นการโทรกลับหมายถึงการอ้างอิงถึงรหัสที่เรียกใช้งานบางส่วนที่ส่งผ่านไปยังรหัสอื่นผ่านพารามิเตอร์ฟังก์ชัน
วัตถุประสงค์คือเพื่อให้รหัสพื้นฐานเรียกรูทีนย่อยที่กำหนดไว้ในระดับที่สูงขึ้น
ตัวอย่างเช่นมันอาจชัดเจนกว่า: การใช้ชุดติดตั้งเพิ่มเติมสำหรับคำขอเครือข่ายใน Android เป็นตัวอย่างนี่เป็นตัวอย่างของการโทรกลับแบบอะซิงโครนัส
หลังจากเริ่มคำขอเครือข่ายแอปสามารถดำเนินการต่อไปได้ ผลลัพธ์ของคำขอเครือข่ายโดยทั่วไปจะได้รับผ่านสองวิธีของการตอบสนองและ onfailure ดูรหัสในส่วนที่เกี่ยวข้อง:
call.enqueue (การโทรกลับใหม่ <HistoryBean> () {@Override โมฆะสาธารณะ onResponse (โทร <HistoryBean> การโทรตอบโต้ <HistoryBean> การตอบสนอง) {HistoryBean Hb = Response.body (); ถ้า (hb == null) return; showtext.append (hb.iserror () ShowText.Append (rb.getTitle () + "/n");ละเว้นการโทรกลับด้านบน ตามคำจำกัดความในวิกิพีเดียรหัสทั้งหมดในคลาสภายในที่ไม่ระบุชื่อสามารถถือได้ ว่าเป็นการอ้างอิงถึงรหัสปฏิบัติการบางอย่างที่ส่งผ่านไปยังรหัสอื่น สองวิธี onResponse และ onfailure เป็นวิธีการโทรกลับ รหัสพื้นฐานคือส่วนคำขอเครือข่ายที่ไม่เปลี่ยนแปลงซึ่งได้รับการเขียนและรูทีนย่อยที่กำหนดโดยระดับที่สูงขึ้นคือการโทรกลับ เนื่องจากการใช้งานเฉพาะถูกส่งมอบให้กับผู้ใช้จึงมีความยืดหยุ่นสูง ข้างต้นเกี่ยวข้องกับวิธีการ enqueue (การโทรกลับ)
ขั้นตอนของวิธีการโทรกลับ
การโทรกลับที่กล่าวถึงข้างต้นเป็นแนวคิดที่พบบ่อยมาก หากคุณใส่ในการเขียนโปรแกรมคุณสามารถพูดได้ว่า:
ในคลาส A วิธี C ในคลาส B เรียกว่าและจากนั้นในคลาส B, เมธอด D ในคลาส A เรียกว่าย้อนกลับ D เป็นวิธีการโทรกลับ คลาส B เป็นรหัสพื้นฐานและคลาส A เป็นรหัสระดับสูง
ดังนั้นผ่านคำอธิบายข้างต้นเราสามารถอนุมานบางสิ่งได้ เพื่อแสดงถึงความเป็นสากลของวิธี D เราใช้แบบฟอร์มอินเตอร์เฟสเพื่อสร้างวิธี D เรียกว่าวิธีการอินเตอร์เฟส หากคลาส B ต้องการเรียกเมธอด D ในคลาส A ดังนั้นคลาส A จะต้องใช้อินเทอร์เฟซนี้ ด้วยวิธีนี้ขึ้นอยู่กับการใช้งานจะมีความหลากหลายทำให้วิธีการยืดหยุ่น
หากคลาส A ต้องการเรียกวิธี C ในคลาส B ดังนั้นคลาส A จะต้องมีการอ้างอิงถึง B มิฉะนั้นจะไม่ถูกเรียก ขั้นตอนนี้เรียกว่าอินเทอร์เฟซการโทรกลับการลงทะเบียน ดังนั้นวิธีการใช้วิธีการโทรย้อนกลับ D ในคลาส A ในคลาส B โดยตรงผ่านวิธีการด้านบน C วิธี C ในคลาส B ยอมรับพารามิเตอร์ประเภทอินเตอร์เฟส จากนั้นเฉพาะในเมธอด C คุณต้องใช้พารามิเตอร์ของประเภทอินเทอร์เฟซนี้เพื่อเรียกเมธอด D ในคลาส B ซึ่งในทางกลับกันเมธอด D ในคลาส A ขั้นตอนนี้เรียกว่าการเรียกใช้อินเตอร์เฟสการโทรกลับ
นอกจากนี้ยังใช้วิธีการในวิธี C ของคลาส B วิธี D ในคลาส A จะต้องเรียกในย้อนกลับซึ่งเป็นการโทรกลับ การโทร B เพื่อปรับแต่งโดยตรงซึ่งถือได้ว่าใช้ API พื้นฐานสำหรับรหัสระดับสูง เรามักจะเขียนโปรแกรมเช่นนี้ B เรียก A เพื่อโทรกลับและ API พื้นฐานต้องการรหัสระดับสูงเพื่อดำเนินการ
สุดท้ายมาสรุปขั้นตอนของวิธีการโทรกลับ:
ตัวอย่างการโทรกลับ
มาเล่นเกมลูกชายกันเถอะและรอให้แม่ของเขาเตรียมอาหารและแจ้งให้ลูกชายของเขามาและกินเป็นตัวอย่างและทำตามขั้นตอนข้างต้นเพื่อเขียนการโทรกลับ
ในตัวอย่างข้างต้นเห็นได้ชัดว่าลูกชายควรใช้อินเทอร์เฟซการโทรกลับและแม่ควรเรียกอินเทอร์เฟซการโทรกลับ ดังนั้นก่อนอื่นเราจะกำหนดอินเทอร์เฟซการโทรกลับจากนั้นให้ลูกชายของเราใช้อินเตอร์เฟสการโทรกลับนี้
รหัสมีดังนี้:
การโทรกลับส่วนต่อประสานสาธารณะ {void eat ();} ลูกชายชั้นสาธารณะใช้การโทรกลับ {แม่ส่วนตัว; // Class A มีการอ้างอิงถึง Void Public Public Void SetMom (Mom Mom) {this.mom = mom; } @Override โมฆะสาธารณะ Eat () {system.out.println ("ฉันมาที่นี่เพื่อทานอาหาร"); } โมฆะสาธารณะ Askmom () {// การเรียกใช้วิธีการที่มีพารามิเตอร์อินเตอร์เฟสผ่านการอ้างอิงถึงคลาส B. System.out.println ("อาหารปรุงสุกหรือไม่"); System.out.println ("ไม่เสร็จฉันกำลังเล่นเกม"); เธรดใหม่ (() -> mom.docook (son.his)). start (); System.out.println ("เล่นเกม ... "); -จากนั้นเราต้องกำหนดชั้นเรียนของแม่ซึ่งมีวิธีการ docook ด้วยพารามิเตอร์อินเตอร์เฟส
Public Class Mom {// เรียกใช้วิธีการโทรกลับโดยใช้พารามิเตอร์อินเตอร์เฟสในเมธอดที่มีพารามิเตอร์อินเตอร์เฟสโมฆะ public void docook (การเรียกกลับกลับ) {เธรดใหม่ (ใหม่ runnable () {@Override โมฆะสาธารณะเรียกใช้ () {ลอง {system.out.println ("การทำอาหาร ... "); thread.sleep (5000); E.PrintStackTrace ();}}}) เริ่มต้น (); -เราผ่านคลาสทดสอบ:
การทดสอบระดับสาธารณะ {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {แม่แม่ = ใหม่แม่ (); ลูกชายลูกชาย = ลูกชายคนใหม่ (); son.setmom (แม่); son.askmom (); -ตัวอย่างนี้เป็นตัวอย่างการโทรกลับทั่วไป คลาส SON ใช้วิธีการโทรกลับของอินเทอร์เฟซ มันเรียก Docook ในคลาส MOM ผ่านวิธี AskMom เพื่อลงทะเบียนอินเทอร์เฟซการโทรกลับซึ่งเทียบเท่ากับการโทรรหัสคลาส B ในชั้นเรียน A. DOCOOK ในคลาส MOM เรียกร้องการกินในคลาส SON เพื่อบอกผลลัพธ์ในคลาส SON
ด้วยวิธีนี้เราใช้การโทรกลับที่ง่ายและกำหนด
การสำรวจตัวอย่างการโทรกลับเพิ่มเติม
ลองดูที่รหัสของคลาสลูกชาย:
ลูกชายชั้นสาธารณะใช้การโทรกลับ {แม่สาธารณะแม่; ลูกชายสาธารณะ (แม่แม่) {this.mom = mom; } โมฆะสาธารณะ askMom () {system.out.println ("อาหารปรุงสุกแล้วหรือยัง?"); System.out.println ("ฉันไม่ได้ทำดีฉันเล่นเกม"); เธรดใหม่ (() -> mom.docook (son.his)). start (); System.out.println ("ฉันกำลังเล่นเกม ... "); } @Override โมฆะสาธารณะ Eat () {system.out.println ("โอเคฉันมาที่นี่เพื่อทานอาหาร"); -ในชั้นเรียนนี้นอกเหนือจากการส่งออกข้อความบางส่วนชิ้นส่วนที่มีประโยชน์จริง ๆ คือ mom.docook (son.his) และเขียนวิธี EAT ใหม่ ดังนั้นเราสามารถย่อการโทรกลับนี้ผ่านรูปแบบของชั้นเรียนที่ไม่ระบุชื่อ รหัสมีดังนี้:
คลาสสาธารณะ callbacktest {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {mom mom = new mom (); เธรดใหม่ (() -> mom.docook (() -> system.out.println ("ฉันทานอาหาร ... "))) เริ่มต้น (); -ยกเลิกคลาส SON และใช้วิธี EAT โดยตรงผ่านชั้นเรียนที่ไม่ระบุชื่อในวิธีการหลัก ในความเป็นจริงคลาสภายในที่ไม่ระบุชื่อเป็นศูนย์รวมของการโทรกลับ
การโทรกลับแบบอะซิงโครนัสและการโทรกลับแบบซิงโครนัส
การโทรกลับ: วิธีการโทร C ในคลาส B จากนั้นเรียกเมธอด d ในคลาส A ผ่านวัตถุคลาส A ในเมธอด C.
มาพูดคุยเกี่ยวกับการซิงโครนัสและการซิงโครไนซ์กันเถอะเรามาพูดคุยเกี่ยวกับแนวคิดของการซิงโครไนซ์ก่อน
ซิงโครนัส
การซิงโครไนซ์หมายความว่าเมื่อเรียกวิธีการหากไม่ได้เรียกใช้วิธีการก่อนหน้านี้จะไม่สามารถเรียกใช้วิธีการใหม่ได้ กล่าวอีกนัยหนึ่งสิ่งต่าง ๆ จะต้องทำทีละคนและคุณสามารถทำสิ่งต่อไปได้
อะซิงโครนัส
ความสัมพันธ์แบบอะซิงโครนัสนั้นสัมพันธ์กับการซิงโครไนซ์คุณไม่จำเป็นต้องรอจนกว่าการโทรวิธีก่อนหน้าจะเสร็จสิ้นก่อนที่จะเรียกวิธีการใหม่ ดังนั้นในการเรียกวิธีการแบบอะซิงโครนัสจึงจำเป็นต้องมีวิธีการเพื่อแจ้งผู้ใช้ของผลการโทรวิธีการ
ใช้วิธีการแบบอะซิงโครนัส
วิธีที่พบบ่อยที่สุดในการใช้แบบอะซิงโครนัสใน Java คือการให้วิธีที่คุณต้องการดำเนินการแบบอะซิงโครนัสในเธรดใหม่
เราจะพบว่าจำเป็นต้องใช้วิธีการในการโทรแบบอะซิงโครนัสเพื่อแจ้งผลการโทรของผู้ใช้ จากข้างต้นเราจะพบว่าวิธีการโทรกลับเหมาะสำหรับการทำสิ่งนี้และแจ้งให้ผู้ใช้ทราบถึงผลการโทรผ่านวิธีการโทรกลับ
การโทรกลับแบบอะซิงโครนัสจะทำในเธรดใหม่เมื่อวิธีการโทร C ของ B
ตัวอย่างข้างต้นของแม่ที่แจ้งให้ลูกชายของเธอทานอาหารเย็นเป็นตัวอย่างของการโทรกลับแบบอะซิงโครนัส ในเธรดใหม่วิธีการ Docook ถูกเรียกและค่าส่งคืนจะได้รับการยอมรับในที่สุดผ่าน EAT แน่นอนหลังจากใช้การเพิ่มประสิทธิภาพ Lamdba สาระสำคัญก็เหมือนกัน
การโทรกลับแบบซิงโครนัสหมายความว่าวิธีการโทร B ไม่ได้อยู่ในเธรดใหม่ เมื่อดำเนินการวิธีนี้ C เราไม่สามารถทำอะไรได้เลยและสามารถรอให้มันเสร็จสมบูรณ์เท่านั้น
ตัวอย่างของการโทรกลับแบบซิงโครนัสและการโทรกลับแบบอะซิงโครนัส
ลองดูตัวอย่างของการโทรกลับแบบซิงโครนัสใน Android:
button.setonclicklistener (ใหม่ view.onclicklistener () {@Override โมฆะสาธารณะ onClick (ดู V) {log.i ("ปุ่ม", "คลิก");}});ปุ่มลงทะเบียนฟังก์ชั่นการโทรกลับผ่าน SetOnClickListener และตามที่เขียนไว้ด้านบนผ่านการอ้างอิงของอินเทอร์เฟซในรูปแบบของคลาสภายในที่ไม่ระบุชื่อ เนื่องจากปุ่มเรียก SetOnClickListener โดยไม่ต้องสร้างเธรดใหม่นี่คือการโทรกลับแบบซิงโครนัส
การโทรกลับแบบอะซิงโครนัสเป็นตัวอย่างที่เราพูดถึงตอนเริ่มต้น:
call.enqueue (การโทรกลับใหม่ <HistoryBean> () {@Override โมฆะสาธารณะ onResponse (โทร <HistoryBean> การโทรตอบโต้ <HistoryBean> การตอบสนอง) {HistoryBean Hb = Response.body (); ถ้า (hb == null) return; showtext.append (hb.iserror () ShowText.Append (rb.getTitle () + "/n");วิธีการ enqueue นี้เป็นวิธีการแบบอะซิงโครนัสในการขอข้อมูลเครือข่ายระยะไกล เมื่อมีการใช้งานภายในมันจะถูกดำเนินการผ่านเธรดใหม่
ผ่านตัวอย่างทั้งสองนี้เราจะเห็นได้ว่าการใช้การเรียกกลับแบบซิงโครนัสและการเรียกกลับแบบอะซิงโครนัสได้รับการออกแบบตามความต้องการที่แตกต่างกัน ไม่สามารถพูดได้ว่าหนึ่งแทนที่อีก ตัวอย่างเช่นในเหตุการณ์การคลิกปุ่มด้านบนหากเป็นการโทรกลับแบบอะซิงโครนัสเอฟเฟกต์การคลิกจะไม่ปรากฏขึ้นทันทีหลังจากผู้ใช้คลิกปุ่มและผู้ใช้จะไม่ดำเนินการอื่น ๆ มันจะรู้สึกแปลก ๆ การโทรกลับแบบอะซิงโครนัสสำหรับคำขอเครือข่ายเนื่องจากทรัพยากรที่ร้องขออาจไม่มีอยู่การเชื่อมต่อเครือข่ายไม่เสถียรและเหตุผลอื่น ๆ ผู้ใช้จึงไม่ชัดเจนเกี่ยวกับการดำเนินการของวิธีการดังนั้นพวกเขาจะใช้การโทรแบบอะซิงโครนัสเริ่มต้นการโทรวิธีและทำสิ่งอื่น ๆ แล้วรอการแจ้งเตือนการโทรกลับ
แอปพลิเคชันของวิธีการโทรกลับในการสื่อสาร
วิธีการโทรกลับที่กล่าวถึงข้างต้นยกเว้นการเรียกกลับของกรอบคำขอเครือข่ายทั้งหมดไม่มีพารามิเตอร์ ลองมาดูการเพิ่มพารามิเตอร์ลงในวิธีการโทรกลับเพื่อใช้ปัญหาการสื่อสารบางอย่าง
หากเราต้องการให้ Class A รับข้อมูลของคลาส B หลังจากการคำนวณและการประมวลผลหลายชุดและทั้งสองคลาสไม่สามารถอ้างถึงข้อมูลของ Class A ได้ เราสามารถพิจารณาการโทรกลับ
ขั้นตอนมีดังนี้:
ขั้นตอนที่กล่าวถึงข้างต้นเป็นนามธรรมเล็กน้อย ลองดูตัวอย่างด้านล่างหนึ่งคือไคลเอนต์และอีกอันคือเซิร์ฟเวอร์ ไคลเอนต์ร้องขอข้อมูลที่ใช้เวลานานของเซิร์ฟเวอร์
ไคลเอนต์คลาสสาธารณะ {เซิร์ฟเวอร์สาธารณะเซิร์ฟเวอร์; คำขอสตริงสาธารณะ; // ลิงก์เซิร์ฟเวอร์และรับการอ้างอิงเซิร์ฟเวอร์ ไคลเอนต์สาธารณะเชื่อมต่อ (เซิร์ฟเวอร์เซิร์ฟเวอร์) {this.server = เซิร์ฟเวอร์; คืนสิ่งนี้; } // ไคลเอนต์ตั้งค่าคำขอสาธารณะ setRequest (คำขอสตริง) {this.request = คำขอ; คืนสิ่งนี้; } // ส่งวิธีการร้องขออย่างไม่หยุดยั้งการแสดงออกของ Lamdba โมฆะสาธารณะ enqueue (server.callback callback) {เธรดใหม่ (()-> server.setCallback (คำขอโทรกลับ)) เริ่มต้น (); - เซิร์ฟเวอร์คลาสสาธารณะ {การตอบสนองสตริงสาธารณะ = "นี่คือ html"; // ลงทะเบียนวิธีการของอินเทอร์เฟซการโทรกลับและส่งผ่านข้อมูลไปยังอินเตอร์เฟสการโทรกลับผ่านพารามิเตอร์โมฆะสาธารณะ setCallback (คำขอสตริงการเรียกกลับการโทรกลับ) {system.out.println ("ได้รับการร้องขอและถูกคำนวณ ... "); เธรดใหม่ (() -> {ลอง {thread.sleep (5000); callback.onResponse (คำขอ + การตอบกลับ);} catch (interruptedException e) {E.printStackTrace (); callback.onfail (e);}}). start (); } // เขียนอินเทอร์เฟซในคลาสที่เป็นเจ้าของข้อมูลการโทรกลับของอินเตอร์เฟสสาธารณะ {void onResponse (การตอบสนองสตริง); เป็นโมฆะ onfail (โยนได้); -ถัดไปลองดูตัวอย่างการทดสอบ:
การเรียกกลับคลาสสาธารณะ {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {ไคลเอนต์ไคลเอนต์ = ไคลเอนต์ใหม่ (); client.connect (เซิร์ฟเวอร์ใหม่ ()). setRequest ("ไฟล์นี้คืออะไร"). enqueue (เซิร์ฟเวอร์ใหม่ callback () {@Override โมฆะสาธารณะ onResponse (การตอบสนองสตริง) {system.out.println (ตอบกลับ); -ผลลัพธ์มีดังนี้:
ได้รับการร้องขอและกำลังคำนวณแล้ว ... ไฟล์นี้คืออะไร? นี่คือ HTML
ข้างต้นคือการสื่อสารผ่านการโทรกลับ
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่าเนื้อหาของบทความนี้จะช่วยในการศึกษาหรือทำงานของทุกคน ฉันหวังว่าจะสนับสนุน Wulin.com เพิ่มเติม!