จาวาสคริปต์มีลักษณะโดยความไม่แน่นอน JavaScript ไม่สามารถรอได้ หากคุณใช้สิ่งที่ต้องรอคุณไม่สามารถหยุดอยู่ที่นั่นและรอผลลัพธ์ที่จะกลับมา ในทางตรงกันข้ามบรรทัดล่างคือการใช้การโทรกลับการโทรกลับ: คุณกำหนดฟังก์ชั่นซึ่งสามารถเรียกได้จนกว่าผลลัพธ์จะพร้อมใช้งาน
รูปแบบการโทรกลับนี้ไม่มีปัญหากับการจัดระเบียบรหัสที่ดี แต่ยังสามารถแก้ปัญหาได้มากมายโดยการเปลี่ยนจากการโทรกลับดั้งเดิมเป็นสัญญา ถือว่าสัญญาเป็นคอนเทนเนอร์ข้อมูลมาตรฐานซึ่งจะทำให้องค์กรรหัสของคุณง่ายขึ้นและกลายเป็นสถาปัตยกรรมตามสัญญา
สัญญาคืออะไร?
สัญญาเป็นวัตถุที่มีวิธีการ ". จากนั้น ()" ซึ่งแสดงถึงผลลัพธ์ของการดำเนินการที่อาจยังไม่ทราบ ไม่ว่าใครจะเข้าถึงวัตถุนี้เขาสามารถใช้วิธีการ ". จากนั้น ()" เพื่อเพิ่มการโทรกลับเพื่อรอการเตือนให้รอการดำเนินการเพื่อให้ได้ผลลัพธ์หรือความล้มเหลวที่ประสบความสำเร็จ
เหตุใดประโยชน์ของการทำสิ่งนี้จึงดีกว่าการโทรกลับ โหมดการโทรกลับมาตรฐานต้องการให้เรามีฟังก์ชั่นการโทรกลับในเวลาเดียวกันเมื่อการประมวลผลคำขอ:
คำขอ (URL, ฟังก์ชั่น (ข้อผิดพลาด, การตอบกลับ) {// จัดการความสำเร็จหรือข้อผิดพลาด}); dosomethingelse ();น่าเสียดายที่รหัสนี้หมายความว่าฟังก์ชั่นการร้องขอนี้ไม่ทราบว่าจะเสร็จสมบูรณ์เมื่อใดและแน่นอนว่าไม่จำเป็น ในที่สุดเราก็ผ่านผลลัพธ์ผ่านการโทรกลับ สิ่งนี้ทำให้การโทรกลับหลายครั้งเพื่อสร้างการโทรกลับซ้อนกันหรือกับดักการโทรกลับ
QueryTheDatabase (คำถาม, ฟังก์ชั่น (ข้อผิดพลาด, ผลลัพธ์) {คำขอ (url, ฟังก์ชั่น (ข้อผิดพลาด, การตอบสนอง) {dosomethingelse (การตอบสนอง, ฟังก์ชั่น (ข้อผิดพลาด, ผลลัพธ์) {doanotherthing (ผลลัพธ์, ฟังก์ชั่น (ข้อผิดพลาด, ผลลัพธ์) {คำขออื่น, ฟังก์ชั่น (ข้อผิดพลาด, การตอบสนอง) {... });สัญญาสามารถแก้ปัญหานี้ได้โดยอนุญาตให้รหัสระดับต่ำสามารถสร้างคำขอแล้วส่งคืนวัตถุซึ่งแสดงถึงการดำเนินการที่ยังไม่เสร็จทำให้ผู้โทรตัดสินใจได้ว่าควรเพิ่มการเรียกกลับแบบใด
สัญญาคืออะไร?
สัญญาเป็นนามธรรมของการเขียนโปรแกรมแบบอะซิงโครนัส มันเป็นวัตถุพร็อกซีที่ส่งคืนค่าหรือโยนข้อยกเว้น โดยทั่วไปวัตถุสัญญามีวิธีการแล้ว วิธีนี้เป็นวิธีที่เราได้รับค่าคืน (ค่าผลลัพธ์ของการดำเนินการตามสัญญาที่ประสบความสำเร็จเรียกว่าการปฏิบัติตาม) หรือโยนข้อยกเว้น (เหตุผลในการปฏิเสธสัญญาเรียกว่าการปฏิเสธ) จากนั้นใช้การเรียกกลับสองทางเลือกเป็นพารามิเตอร์ซึ่งเราสามารถเรียก onfulfilled และ onrejected:
var promise = dosomethingaync ()
สัญญาแล้ว (onfulfilled, onrejected)
เมื่อสัญญานี้ได้รับการแก้ไขนั่นคือหลังจากกระบวนการแบบอะซิงโครนัสเสร็จสมบูรณ์ไม่ว่าจะเป็น onfulfilled และ onrejected จะถูกเรียก
ดังนั้นสัญญามีสามรัฐที่แตกต่างกันดังต่อไปนี้:
■รอการสัญญา - สถานะเริ่มต้นของสัญญา
■ความมุ่งมั่นในการดำเนินการตามความมุ่งมั่นที่ประสบความสำเร็จ
■ปฏิเสธการปฏิเสธความมุ่งมั่น - รัฐที่สัญญาล้มเหลว
การใช้ไฟล์อ่านเป็นกรณีต่อไปนี้เป็นสิ่งที่ควรทำหลังจากอ่านไฟล์โดยใช้การโทรกลับ (การพิมพ์เอาต์พุต):
ReadFile (ฟังก์ชั่น (err, data) {ถ้า (err) return console.error (err) console.log (data)})หากฟังก์ชั่น readfile ของเราส่งคืนสัญญาเราสามารถใช้ตรรกะเดียวกันดังนี้ (การพิมพ์เอาต์พุต):
var promise = readfile ()
สัญญาแล้ว (console.log, console.error)
ที่นี่เรามีสัญญามูลค่าที่แสดงถึงการดำเนินการแบบอะซิงโครนัส เราสามารถผ่านสัญญามูลค่านี้ได้ตลอดเวลา ทุกคนที่เข้าถึงค่านี้สามารถใช้เพื่อบริโภค ไม่ว่าการดำเนินการแบบอะซิงโครนัสที่แสดงโดยค่านี้จะเสร็จสมบูรณ์หรือไม่เสร็จสมบูรณ์เรายังสามารถตรวจสอบให้แน่ใจว่าผลลัพธ์แบบอะซิงโครนัสจะไม่เปลี่ยนแปลงเนื่องจากการดำเนินการแบบอะซิงโครนัสที่แสดงโดยสัญญานี้จะถูกดำเนินการเพียงครั้งเดียว
เข้าใจคำสัญญา
สัญญาอาจแตกต่างจากสัญชาตญาณรายวัน เพื่อที่จะเข้าใจมันต้องคำนึงถึงหลักการสำคัญบางประการ:. จากนั้น () กลับมาสัญญาใหม่เสมอ ดังที่แสดงในรหัสต่อไปนี้:
var promise = readfile ()
var promise2 = promise จากนั้น (readanotherfile, console.error)
ที่นี่พารามิเตอร์ readanotherfile, console.error แสดงถึงการกระทำที่สมบูรณ์หลังจากการดำเนินการแบบอะซิงโครนัสประสบความสำเร็จหรือการกระทำที่เกิดขึ้นหลังจากความล้มเหลวสำเร็จ กล่าวคือหลังจากฟังก์ชั่น readanotherfile ถูกดำเนินการมิฉะนั้นบันทึกการพิมพ์ที่ล้มเหลวไม่ถูกต้อง การใช้งานนี้เป็นไปได้ในสองวิธีเท่านั้น
มาดูรหัสต่อไปนี้:
var promition = readfile () var promitu2 = promise. จากนั้น (ฟังก์ชั่น (ข้อมูล) {return readanotherfile () // ถ้า readfile สำเร็จให้ดำเนินการ readanotherfile}, ฟังก์ชั่น (err) {console.error (err) // ถ้า readfile ไม่สำเร็จ ผลการดำเนินการของฟังก์ชัน ReadAnotherfileเพราะจากนั้นส่งคืนสัญญาก็หมายความว่าสามารถใช้สัญญาได้โดยการผูกมัดห่วงโซ่อนุกรมซึ่งสามารถหลีกเลี่ยงการโทรกลับนรก:
readfile (). จากนั้น (readanotherfile). จากนั้น (dosomethingelse). จากนั้น (... )
มีสองส่วนของกฎสัญญาที่ต้องแยกออก:
(1). จากนั้น () ส่งคืนสัญญาใหม่เสมอ ทุกครั้งที่คุณเรียกมันว่ามันไม่สำคัญว่าการโทรกลับทำอะไรเพราะ. จากนั้น () ให้สัญญากับคุณก่อนที่จะเรียกการโทรกลับ พฤติกรรมของการโทรกลับมีผลต่อการดำเนินการตามสัญญาสัญญาเท่านั้น หากการโทรกลับส่งคืนค่าสัญญาจะใช้ค่านั้น หากค่านี้เป็นสัญญาให้ส่งคืนค่าหลังจากการดำเนินการตามสัญญากับค่านี้ หากการเรียกกลับเกิดข้อผิดพลาดสัญญาจะปฏิเสธข้อผิดพลาด
(2) สัญญาที่ส่งคืนโดย. จากนั้น () เป็นสัญญาใหม่ซึ่งแตกต่างจากที่เรียกว่า () ที่เรียกว่า ห่วงโซ่ยาวของสัญญาบางครั้งซ่อนความจริงที่ว่าไม่ว่าอะไรก็ตามทุกครั้งที่โทร () จะสร้างสัญญาใหม่ สิ่งที่คุณต้องทราบที่นี่คือสิ่งที่คุณต้องพิจารณาจริงๆคือการโทรครั้งสุดท้ายของคุณจากนั้น () อาจแสดงถึงความล้มเหลวดังนั้นหากคุณไม่พบความล้มเหลวนี้มันเป็นเรื่องง่ายที่จะทำให้ข้อผิดพลาดของคุณหายไป
บางคนคิดว่าการเรียกโซ่ () () การโทรนั้นคล้ายกับสไตล์ที่คล่องแคล่วมาก แต่ห่วงโซ่สัญญายาวจะสับสนและในที่สุดก็แบ่งออกเป็นฟังก์ชั่นที่มีความหมาย:
ฟังก์ชั่น getTasks () {return $ http.get ('http://example.com/api/v1/tasks'). จากนั้น (ฟังก์ชั่น (การตอบสนอง) {return response.data;});} function getMytasks () {return getTasks () -ในตัวอย่างนี้ฟังก์ชั่นทั้งสองแต่ละรายการจะได้รับสัญญาซึ่งมีฟังก์ชั่นการโทรกลับ
คำสัญญาที่น่าสนใจ
สัญญาเดียวกันสามารถยอมรับการโทรกลับจำนวนใด ๆ เมื่อสัญญาได้รับการแก้ไขและดำเนินการฟังก์ชั่นการโทรกลับทั้งหมดจะถูกเรียก นอกจากนี้สัญญายังสามารถยอมรับการโทรกลับใหม่หลังจากได้รับการแก้ไขและดำเนินการ การเรียกกลับเหล่านี้สามารถเรียกได้ในแบบปกติซึ่งช่วยให้เราสามารถใช้การเรียกกลับเพื่อใช้แคชแบบง่าย ๆ :
var taskspromise; ฟังก์ชั่น getTasks () {taskPromise = taskPromise || getTasksfromtheserver (); ส่งคืน taskpromise;}ในกรณีนี้ฟังก์ชั่น GetTasks () สามารถเรียกได้ว่ามีหลายครั้งที่จะส่งคืนสัญญาของฟันทองแดงเสมอซึ่งฟังก์ชั่น getTasksFromTheServer () จะถูกเรียกเพียงครั้งเดียว
การใช้งานของ NodeJS ที่สัญญาไว้ข้างต้นคือเนื้อหาทั้งหมดที่ฉันแบ่งปันกับคุณ ฉันหวังว่าคุณจะให้ข้อมูลอ้างอิงและฉันหวังว่าคุณจะสนับสนุน wulin.com มากขึ้น