เริ่มต้นกับสัญญาจาวาสคริปต์
รหัสไม่ตรงกัน มีประโยชน์สำหรับการปฏิบัติงานที่เป็น ต้องใช้เวลามาก แต่แน่นอนมันเป็น ไม่ไร้ข้อเสีย. รหัส Async ใช้ ฟังก์ชั่นการโทรกลับ เพื่อประมวลผลผลลัพธ์อย่างไรก็ตามฟังก์ชันการเรียกกลับ ไม่สามารถคืนค่า ฟังก์ชัน JavaScript ทั่วไปสามารถ.
ดังนั้นพวกเขาไม่เพียง แต่กำจัดความสามารถของเราในการควบคุม การดำเนินการของฟังก์ชั่น แต่ยังทำ การจัดการข้อผิดพลาด ค่อนข้างยุ่งยาก นี่คือที่ คำมั่นสัญญา
วัตถุ เข้ามาในขณะที่มันมีจุดมุ่งหมายเพื่อเติมในบางส่วนของ หลุมบ่อในการเข้ารหัสแบบอะซิงโครนัส.
คำมั่นสัญญา
เป็นเทคนิค วัตถุภายในมาตรฐาน ใน JavaScript หมายถึงว่ามันมา บิวท์อิน JavaScript. มันถูกใช้เพื่อเป็นตัวแทนของ ผลลัพธ์สุดท้ายของบล็อกรหัสแบบอะซิงโครนัส (หรือสาเหตุที่ทำให้รหัสล้มเหลว) และมีวิธีการควบคุม การทำงานของรหัสอะซิงโครนัส.
วากยสัมพันธ์
เราสามารถสร้าง ตัวอย่างของ คำมั่นสัญญา
วัตถุ ใช้ ใหม่
คำสำคัญ:
สัญญาใหม่ (ฟังก์ชั่น (แก้ไข, ปฏิเสธ) );
ฟังก์ชั่น ผ่านเป็นพารามิเตอร์ ไปที่ สัญญา ()
คอนสตรัคเป็นที่รู้จักกันในนาม ผู้ปฏิบัติการ. มันถือรหัสไม่ตรงกันและ มีสองพารามิเตอร์ของ ฟังก์ชัน
ชนิด, เรียกว่า แก้ไข
และ ปฏิเสธ
ฟังก์ชั่น (เพิ่มเติมเกี่ยวกับสิ่งเหล่านี้ในไม่ช้า).
รัฐของ คำมั่นสัญญา
วัตถุ
สถานะเริ่มต้น ของ คำมั่นสัญญา
วัตถุถูกเรียก อยู่ระหว่างดำเนินการ. ในสถานะนี้ผลลัพธ์ของการคำนวณแบบอะซิงโครนัส ไม่ได้อยู่.
สถานะเริ่มต้นที่รอดำเนินการเปลี่ยนเป็น สม สถานะเมื่อการคำนวณเป็น ที่ประสบความสำเร็จ. ผลการคำนวณ มีอยู่ในสถานะนี้.
ในกรณีการคำนวณแบบอะซิงโครนัส ล้มเหลว, คำมั่นสัญญา
วัตถุย้ายไปที่ ปฏิเสธ สถานะจากเริ่มต้น อยู่ระหว่างดำเนินการ สถานะ. ในสถานะนี้ เหตุผลของการคำนวณที่ล้มเหลว (เช่นข้อความแสดงข้อผิดพลาด) มีให้บริการ.
ที่จะไปจาก อยู่ระหว่างดำเนินการ ไปยัง สม สถานะ, แก้ไข ()
ถูกเรียก. ที่จะไปจาก อยู่ระหว่างดำเนินการ ไปยัง ปฏิเสธ สถานะ, ปฏิเสธ()
ถูกเรียก.
แล้วก็
และ จับ
วิธีการ
เมื่อรัฐ การเปลี่ยนแปลงจาก อยู่ระหว่างดำเนินการ ไปยัง สม, ตัวจัดการเหตุการณ์ของ คำมั่นสัญญา
ของวัตถุ แล้วก็
วิธี ถูกประหารชีวิต และเมื่อถึงสถานะ การเปลี่ยนแปลงจาก อยู่ระหว่างดำเนินการ ไปยัง ปฏิเสธ, ตัวจัดการเหตุการณ์ของ คำมั่นสัญญา
ของวัตถุ จับ
วิธี ถูกประหารชีวิต.
ตัวอย่างที่ 1
“Non-Promisified” รหัส
สมมติว่ามี hello.txt
ไฟล์ที่มี “สวัสดี” คำ. นี่คือวิธีที่เราสามารถเขียนคำขอ AJAX ให้ ดึงไฟล์นั้น และ แสดงเนื้อหา, โดยไม่ต้องใช้ คำมั่นสัญญา
วัตถุ:
ฟังก์ชั่น getTxt () let xhr = ใหม่ XMLHttpRequest (); xhr.open ('GET', 'hello.txt'); xhr.overrideMimeType ( 'text / plain'); xhr.send (); xhr.onload = function () ลอง switch (this.status) case 200: document.write (this.response); ทำลาย; เคส 404: โยน 'ไม่พบไฟล์'; เริ่มต้น: โยน 'ไม่สามารถดึงไฟล์'; catch (err) console.log (err); getTxt ();
หากเนื้อหาของไฟล์ได้รับการ ดึงข้อมูลสำเร็จแล้ว, นั่นคือ. รหัสสถานะการตอบกลับคือ 200, ข้อความตอบกลับคือ เขียนลงในเอกสาร. หากเป็นไฟล์ ไม่พบ (สถานะ 404), “ไม่พบไฟล์” ข้อความแสดงข้อผิดพลาดถูกส่งออกไป มิฉะนั้น a ข้อความแสดงข้อผิดพลาดทั่วไป ระบุความล้มเหลวของการดึงไฟล์ที่ถูกโยน.
“Promisified” รหัส
ตอนนี้มา แนะนำรหัสด้านบน:
ฟังก์ชั่น getTxt () กลับสัญญาใหม่ (ฟังก์ชั่น (แก้ไขปฏิเสธ) ให้ xhr = ใหม่ XMLHttpRequest (); xhr.open ('GET', 'hello.txt'); xhr.overrideMimeType ('ข้อความ / ธรรมดา'); xhr.send (); xhr.onload = ฟังก์ชั่น () switch (this.status) กรณี 200: แก้ไข (this.response); กรณี 404: ปฏิเสธ ('ไม่พบไฟล์'); เริ่มต้น: ปฏิเสธ ('ล้มเหลวในการ ดึงไฟล์ ');;); getTxt (). จากนั้น (function (txt) document.write (txt);) catch (ฟังก์ชั่น (err) console.log (err););
getTxt ()
ฟังก์ชั่นตอนนี้รหัส ส่งคืนอินสแตนซ์ใหม่ของ คำมั่นสัญญา
วัตถุ, และฟังก์ชั่นการทำงานของมันจะเก็บโค้ดอะซิงโครนัสไว้ก่อน.
เมื่อ รหัสสถานะการตอบกลับคือ 200, คำมั่นสัญญา
คือ สม โดย การเรียกร้อง แก้ไข ()
(การตอบสนองถูกส่งผ่านเป็นพารามิเตอร์ของ แก้ไข ()
) เมื่อรหัสสถานะคือ 404 หรือรหัสอื่น คำมั่นสัญญา
คือ ปฏิเสธ การใช้ ปฏิเสธ()
(พร้อมข้อความแสดงข้อผิดพลาดที่เหมาะสมเป็นพารามิเตอร์ของ ปฏิเสธ()
).
ตัวจัดการเหตุการณ์สำหรับ แล้ว ()
และ จับ()
วิธีการ ของ คำมั่นสัญญา
วัตถุคือ เพิ่มในตอนท้าย.
เมื่อ คำมั่นสัญญา
คือ สม, ผู้จัดการของ แล้ว ()
วิธีการทำงาน อาร์กิวเมนต์ของมันคือ พารามิเตอร์ส่งผ่านจาก แก้ไข ()
. ภายในตัวจัดการเหตุการณ์ข้อความตอบกลับ (รับเป็นอาร์กิวเมนต์) คือ เขียนลงในเอกสาร.
เมื่อ คำมั่นสัญญา
คือ ปฏิเสธ, ตัวจัดการเหตุการณ์ของ จับ()
วิธีการทำงาน, บันทึกข้อผิดพลาด.
ข้อได้เปรียบหลัก ของรุ่น Promisified ข้างต้นคือ การจัดการข้อผิดพลาด. แทนที่จะโยนข้อยกเว้น Uncaught รอบ ๆ - เหมือนในเวอร์ชันที่ไม่ได้รับสัญญา - ข้อความความล้มเหลวที่เหมาะสม จะถูกส่งกลับและเข้าสู่ระบบ.
แต่มันไม่ใช่แค่ การคืน ของ ข้อความล้มเหลว แต่ยังของ ผลลัพธ์ของการคำนวณแบบอะซิงโครนัส ที่สามารถเป็นประโยชน์อย่างแท้จริงสำหรับเรา หากต้องการดูสิ่งนั้นเราจะต้องขยายตัวอย่างของเรา.
ตัวอย่างที่ 2
“Non-Promisified” รหัส
แทนที่จะแสดงเพียงข้อความจาก hello.txt
, ฉันต้องการ รวมกับ “โลก” คำ และแสดงบนหน้าจอ หลังจากหมดเวลา 2 วินาที. นี่คือรหัสที่ฉันใช้:
ฟังก์ชั่น getTxt () let xhr = ใหม่ XMLHttpRequest (); xhr.open ('GET', 'hello.txt'); xhr.overrideMimeType ( 'text / plain'); xhr.send (); xhr.onload = function () ลอง switch (this.status) case 200: document.write (concatTxt (this.response)); ทำลาย; เคส 404: โยน 'ไม่พบไฟล์'; เริ่มต้น: โยน 'ไม่สามารถดึงไฟล์'; catch (err) console.log (err); function concatTxt (res) setTimeout (function () return (res + 'World'), 2000); getTxt ();
ในรหัสสถานะ 200 concatTxt ()
ฟังก์ชั่นที่เรียกว่า ต่อข้อความตอบกลับเข้ากับ “โลก” คำ ก่อนที่จะเขียนลงในเอกสาร.
แต่รหัสนี้ จะไม่ทำงานตามที่ต้องการ. setTimeout ()
ฟังก์ชั่นการโทรกลับ ไม่สามารถคืนค่าสตริงที่ต่อกันได้. สิ่งที่จะพิมพ์ออกมาในเอกสารคือ ไม่ได้กำหนด
เพราะนั่นคือ อะไร concatTxt ()
ผลตอบแทน.
“Promisified” รหัส
ดังนั้นเพื่อให้โค้ดทำงานได้ แนะนำรหัสด้านบน, รวมไปถึง concatTxt ()
:
ฟังก์ชั่น getTxt () กลับสัญญาใหม่ (ฟังก์ชั่น (แก้ไขปฏิเสธ) ให้ xhr = ใหม่ XMLHttpRequest (); xhr.open ('GET', 'hello.txt'); xhr.overrideMimeType ('ข้อความ / ธรรมดา'); xhr.send (); xhr.onload = ฟังก์ชั่น () switch (this.status) กรณี 200: แก้ไข (this.response); กรณี 404: ปฏิเสธ ('ไม่พบไฟล์'); เริ่มต้น: ปฏิเสธ ('ล้มเหลวในการ ดึงไฟล์ ');;); function concatTxt (txt) ส่งคืนสัญญาใหม่ (ฟังก์ชั่น (แก้ไขปฏิเสธ) setTimeout (ฟังก์ชั่น () แก้ไข (txt + 'World');, 2000);); getTxt (). then ((txt) => return concatTxt (txt);). จากนั้น ((txt) => document.write (txt);). catch ((err) => คอนโซล log (err););
เหมือนกับ getTxt ()
, concatTxt ()
ฟังก์ชั่นยัง ส่งคืนใหม่ คำมั่นสัญญา
วัตถุ แทนการตัดแบ่งข้อความ คำมั่นสัญญา
ส่งคืนโดย concatTxt ()
คือ แก้ไขได้ภายในฟังก์ชั่นการโทรกลับของ setTimeout ()
.
ใกล้ถึงจุดสิ้นสุดของโค้ดด้านบนตัวจัดการเหตุการณ์ของแรก แล้ว ()
วิธีการทำงานเมื่อ คำมั่นสัญญา
ของ getTxt ()
คือ สม, เช่นเมื่อไฟล์เป็น ดึงข้อมูลสำเร็จแล้ว. ภายในตัวจัดการนั้น, concatTxt ()
ถูกเรียก และ คำมั่นสัญญา
ส่งคืนโดย concatTxt ()
ถูกส่งคืน.
ตัวจัดการเหตุการณ์ของวินาที แล้ว ()
วิธีการทำงานเมื่อ คำมั่นสัญญา
ส่งคืนโดย concatTxt ()
คือ สม, เช่น การหมดเวลาสองวินาทีสิ้นสุดลง และ แก้ไข ()
ถูกเรียก ด้วยสตริงที่ต่อกันเป็นพารามิเตอร์.
ในที่สุด, จับ()
จับข้อยกเว้นและข้อความล้มเหลวทั้งหมด จากสัญญาทั้งสอง.
ในเวอร์ชั่น Promisified นี้ “สวัสดีชาวโลก” สตริงจะเป็น พิมพ์สำเร็จแล้ว ไปที่เอกสาร.