อย่างที่คุณอาจทราบสภาพแวดล้อมการดำเนินการของภาษา JavaScript คือ "เธรดเดี่ยว"
"เธรดเดี่ยว" ที่เรียกว่า "งานหนึ่งสามารถเสร็จสิ้นได้ในแต่ละครั้งเท่านั้น หากมีหลายงานคุณต้องเข้าคิวให้ทำภารกิจก่อนหน้าให้เสร็จสิ้นงานถัดไปและอื่น ๆ
ข้อได้เปรียบของโมเดลนี้คือมันค่อนข้างง่ายที่จะนำไปใช้และสภาพแวดล้อมการดำเนินการค่อนข้างง่าย การดำเนินการของโปรแกรมทั้งหมด เบราว์เซอร์ทั่วไปไม่ตอบสนอง (การตายปลอม) บ่อยครั้งเนื่องจากรหัส JavaScript บางชิ้นทำงานเป็นเวลานาน (เช่นวนซ้ำ) ทำให้หน้าทั้งหมดติดอยู่ในสถานที่นี้และงานอื่น ๆ ไม่สามารถดำเนินการได้
เพื่อแก้ปัญหานี้ภาษาจาวาสคริปต์แบ่งโหมดการดำเนินการของงานออกเป็นสองประเภท: ซิงโครนัส (ซิงโครนัส) และอะซิงโครนัส (อะซิงโครนัส)
"โหมดซิงโครนัส" เป็นโหมดของส่วนก่อนหน้าและงานหลังรอให้งานก่อนหน้าจบลงแล้วดำเนินการ แตกต่างกันอย่างสิ้นเชิงและแต่ละงานมีฟังก์ชั่นการโทรกลับอย่างน้อยหนึ่งรายการ (การเรียกกลับ) เพื่อสิ้นสุดดังนั้นคำสั่งการดำเนินการของโปรแกรมคือและงาน
"โหมด async" มีความสำคัญมาก ในด้านเบราว์เซอร์การดำเนินงานระยะยาวควรดำเนินการแบบอะซิงโครนัสเพื่อหลีกเลี่ยงเบราว์เซอร์จากการสูญเสียการตอบสนอง ทางด้านเซิร์ฟเวอร์ "โหมดอะซิงโครนัส" เป็นโหมดเดียวเนื่องจากสภาพแวดล้อมการดำเนินการเป็นเธรดเดี่ยวหากคำขอ HTTP ทั้งหมดได้รับอนุญาตให้ดำเนินการแบบซิงโครนัสประสิทธิภาพของเซิร์ฟเวอร์จะลดลงอย่างรวดเร็วและจะสูญเสียการตอบกลับในไม่ช้า
1. ฟังก์ชั่นการโทรกลับ
นี่เป็นวิธีพื้นฐานที่สุดของการเขียนโปรแกรมแบบอะซิงโครนัส
สมมติว่ามีสองฟังก์ชั่น F1 และ F2 หลังรอผลการดำเนินการของอดีต
การคัดลอกรหัสมีดังนี้:
F1 ();
f2 ();
หาก F1 เป็นงานที่ใช้เวลานานคุณสามารถพิจารณาการเขียน F1 ใหม่และเขียน F2 เป็นฟังก์ชั่นการโทรกลับของ F1
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น F1 (โทรกลับ) {
settimeout (function () {
// รหัสงานของ F1
การโทรกลับ ();
}, 1,000);
-
รหัสดำเนินการเป็นเช่นนี้:
F1 (F2);
ข้อได้เปรียบของฟังก์ชั่นการโทรกลับคือพวกเขาเป็นเรื่องง่ายเข้าใจและปรับใช้และข้อเสียคือพวกเขาไม่เอื้อต่อการอ่านและการบำรุงรักษารหัส วุ่นวายมากและแต่ละงานสามารถระบุฟังก์ชั่นการโทรกลับได้เพียงหนึ่งเดียวเท่านั้น
2. การตรวจสอบเหตุการณ์
อีกแนวคิดหนึ่งคือการใช้โมเดลที่ขับเคลื่อนด้วยเหตุการณ์ การดำเนินงานของงานไม่ได้ขึ้นอยู่กับลำดับของรหัส แต่ว่าเหตุการณ์เกิดขึ้นหรือไม่
ลองใช้ F1 และ F2 เป็นตัวอย่าง ก่อนอื่นให้ผูกกิจกรรมสำหรับ F1 (วิธีการเขียน jQuery ที่ใช้ที่นี่)
การคัดลอกรหัสมีดังนี้:
f1.on ('เสร็จสิ้น', f2);
บรรทัดของรหัสข้างต้นหมายความว่าเมื่อเหตุการณ์ที่เกิดขึ้นเกิดขึ้นใน F1, F2 จะถูกดำเนินการ จากนั้นเขียนใหม่ F1:
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น f1 () {
settimeout (function () {
// รหัสงานของ F1
f1.trigger ('เสร็จ');
}, 1,000);
-
F1.Trigger ('เสร็จแล้ว') หมายความว่าหลังจากการดำเนินการเสร็จสิ้นเหตุการณ์ที่เสร็จสิ้นจะถูกเรียกใช้ทันทีดังนั้นจึงเริ่มดำเนินการ F2
ข้อได้เปรียบของวิธีนี้คือมันค่อนข้างเข้าใจง่าย ข้อเสียคือโปรแกรมทั้งหมดจะกลายเป็นเหตุการณ์ที่เกิดขึ้นและกระบวนการดำเนินการจะไม่ชัดเจนมาก
3. เผยแพร่/สมัครสมาชิก
"เหตุการณ์" ในส่วนก่อนหน้านี้สามารถเข้าใจได้อย่างสมบูรณ์ว่าเป็น "สัญญาณ"
เราคิดว่ามี "ศูนย์สัญญาณ" สิ่งนี้เรียกว่า "Publish-Subscribe Pattern" หรือที่เรียกว่า "ผู้สังเกตการณ์รูปแบบ"
มีการใช้งานมากมายของรุ่นนี้
ขั้นแรก F2 สมัครสมาชิกสัญญาณ "เสร็จสิ้น" ไปยัง "ศูนย์สัญญาณ" jQuery
การคัดลอกรหัสมีดังนี้:
jQuery.subscribe ("เสร็จสิ้น", f2);
จากนั้น F1 จะถูกเขียนใหม่ดังนี้:
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น f1 () {
settimeout (function () {
// รหัสงานของ F1
jQuery.publish ("เสร็จสิ้น");
}, 1,000);
-
jQuery.publish ("เสร็จสิ้น") หมายความว่าหลังจากการดำเนินการ F1 เสร็จสิ้นสัญญาณ "เสร็จสิ้น" จะถูกส่งไปยัง "ศูนย์สัญญาณ" jQuery ซึ่งจะกระตุ้นการดำเนินการของ F2
นอกจากนี้หลังจากดำเนินการ F2 แล้วการยกเลิกการสมัครก็สามารถยกเลิกได้
การคัดลอกรหัสมีดังนี้:
jQuery.unsubscribe ("เสร็จสิ้น", f2);
ลักษณะของวิธีการนี้คล้ายกับ "การฟังเหตุการณ์" แต่ดีกว่าหลังอย่างมาก เนื่องจากเราสามารถตรวจสอบการทำงานของโปรแกรมโดยดูที่ "ศูนย์ข้อความ" เพื่อทำความเข้าใจว่ามีสัญญาณกี่สัญญาณและจำนวนสมาชิกสำหรับแต่ละสัญญาณ
4. สัญญาวัตถุ
วัตถุสัญญาเป็นข้อกำหนดที่เสนอโดยคณะทำงาน CommonJS โดยมีวัตถุประสงค์เพื่อให้อินเทอร์เฟซแบบครบวงจรสำหรับการเขียนโปรแกรมแบบอะซิงโครนัส
พูดง่ายๆคือความคิดของมันคืองานอะซิงโครนัสแต่ละครั้งจะส่งคืนวัตถุสัญญาซึ่งมีวิธีการที่อนุญาตให้ระบุฟังก์ชั่นการเรียกกลับ ตัวอย่างเช่นฟังก์ชั่นการโทรกลับ F2 ของ F1 สามารถเขียนเป็น:
การคัดลอกรหัสมีดังนี้:
f1 (). จากนั้น (f2);
F1 จะต้องมีการเขียนใหม่ดังนี้ (การใช้งาน jQuery ถูกนำมาใช้ที่นี่):
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น f1 () {
var dfd = $ .deferred ();
settimeout (function () {
// รหัสงานของ F1
dfd.resolve ();
}, 500);
ส่งคืน dfd.promise;
-
ข้อดีของการเขียนด้วยวิธีนี้คือฟังก์ชั่นการโทรกลับได้กลายเป็นวิธีการเขียนโซ่และการไหลของโปรแกรมสามารถมองเห็นได้ชัดเจนมากและมีชุดวิธีสนับสนุนที่สมบูรณ์ซึ่งสามารถรับรู้ฟังก์ชั่นที่ทรงพลังมากมาย
ตัวอย่างเช่นระบุฟังก์ชั่นการโทรกลับหลายรายการ:
f1 (). จากนั้น (f2). จากนั้น (f3);
ตัวอย่างเช่นระบุฟังก์ชั่นการโทรกลับเมื่อเกิดข้อผิดพลาด:
f1 (). จากนั้น (f2) .fail (f3);
ยิ่งไปกว่านั้นมันมีข้อได้เปรียบที่ไม่มีวิธีการสามวิธีก่อนหน้านี้: หากงานเสร็จสมบูรณ์ให้เพิ่มฟังก์ชั่นการโทรกลับและฟังก์ชั่นการโทรกลับจะถูกดำเนินการทันที ดังนั้นคุณไม่ต้องกังวลเกี่ยวกับการขาดเหตุการณ์หรือสัญญาณ ข้อเสียของวิธีนี้คือมันค่อนข้างยากที่จะเขียนและเข้าใจ