โดยพื้นฐานแล้วคุณกำลังถามว่าอะไรคือความแตกต่างระหว่างสองสิ่งนี้ ( p
คำสัญญาที่สร้างขึ้นจากรหัสก่อนหน้านี้อยู่ที่ไหน):
return p.then(...).catch(...);
และ
return p.catch(...).then(...);
มีความแตกต่างไม่ว่าจะเมื่อ p แก้ไขหรือปฏิเสธ แต่ความแตกต่างเหล่านั้นมีความสำคัญหรือไม่ขึ้นอยู่กับสิ่งที่โค้ดภายใน.then()
หรือ.catch()
ตัวจัดการทำ
จะเกิดอะไรขึ้นเมื่อp
แก้ไข:
ในรูปแบบแรกเมื่อp
แก้ไขแล้ว.then()
ตัวจัดการจะถูกเรียก หาก.then()
ตัวจัดการนั้นส่งคืนค่าหรือคำสัญญาอื่นที่แก้ไขได้ในที่สุด.catch()
ตัวจัดการนั้นจะถูกข้ามไป แต่ถ้า.then()
ตัวจัดการโยนหรือตอบกลับคำสัญญาที่ปฏิเสธในที่สุด.catch()
ตัวจัดการจะดำเนินการสำหรับทั้งการปฏิเสธในสัญญาเดิมp
แต่ยังมีข้อผิดพลาดที่เกิดขึ้นใน.then()
ตัวจัดการด้วย
ในโครงการที่สองเมื่อ p
แก้ไขแล้ว.then()
ตัวจัดการจะถูกเรียก หาก.then()
ตัวจัดการนั้นพ่นหรือตอบกลับคำสัญญาที่ปฏิเสธในที่สุด.catch()
ตัวจัดการจะไม่สามารถจับได้เพราะมันอยู่ตรงหน้ามันในห่วงโซ่
นั่นคือความแตกต่าง # 1 หาก.catch()
ตัวจัดการเป็น AFTER ก็สามารถตรวจจับข้อผิดพลาดภายใน.then()
ตัวจัดการได้เช่นกัน
จะเกิดอะไรขึ้นเมื่อถูกp
ปฏิเสธ:
ตอนนี้ในรูปแบบแรกหากคำสัญญาp
ปฏิเสธ.then()
ตัวจัดการจะถูกข้ามไปและ.catch()
ตัวจัดการจะถูกเรียกตามที่คุณคาดหวัง สิ่งที่คุณทำในไฟล์.catch()
ตัวจัดการจะกำหนดสิ่งที่ส่งคืนเป็นผลลัพธ์สุดท้าย หากคุณส่งคืนค่าจาก.catch()
ตัวจัดการหรือส่งคืนคำสัญญาที่แก้ไขได้ในที่สุดโซ่สัญญาจะเปลี่ยนเป็นสถานะที่แก้ไขแล้วเนื่องจากคุณ "จัดการ" ข้อผิดพลาดและส่งคืนตามปกติ หากคุณโยนหรือส่งคืนคำสัญญาที่ปฏิเสธใน.catch()
ตัวจัดการสัญญาที่ส่งคืนจะยังคงถูกปฏิเสธ
ในรูปแบบที่สองหากคำสัญญาp
ปฏิเสธระบบ.catch()
จะเรียกตัวจัดการ หากคุณส่งคืนค่าปกติหรือคำสัญญาที่แก้ไขจาก.catch()
ตัวจัดการในที่สุด(ดังนั้น "การจัดการ" ข้อผิดพลาด) โซ่สัญญาจะเปลี่ยนเป็นสถานะที่แก้ไขแล้วและ.then()
ตัวจัดการหลังจากที่.catch()
จะถูกเรียก
นั่นคือความแตกต่าง # 2 หาก.catch()
ตัวจัดการอยู่ก่อนจะสามารถจัดการข้อผิดพลาดและอนุญาตให้.then()
ตัวจัดการยังคงถูกเรียก
ควรใช้เมื่อใด:
ใช้รูปแบบแรกหากคุณต้องการ.catch()
ตัวจัดการเพียงคนเดียวที่สามารถจับข้อผิดพลาดทั้งในสัญญาเดิมp
หรือใน.then()
ตัวจัดการและการปฏิเสธจากp
ควรข้าม.then()
ตัวจัดการ
ใช้รูปแบบที่สองหากคุณต้องการจับข้อผิดพลาดในสัญญาเดิมp
และอาจ (ขึ้นอยู่กับเงื่อนไข) ปล่อยให้ห่วงโซ่สัญญาดำเนินการต่อเมื่อได้รับการแก้ไขแล้วจึงเรียกใช้.then()
ตัวจัดการ
ตัวเลือกอื่น ๆ
มีอีกหนึ่งทางเลือกในการใช้การโทรกลับทั้งสองแบบที่คุณสามารถส่งผ่านได้.then()
ใน:
p.then(fn1, fn2)
สิ่งนี้รับประกันได้ว่าจะมีเพียงหนึ่งในfn1
หรือfn2
จะถูกเรียก ถ้าp
แก้ไขได้ก็fn1
จะเรียก. ถ้าp
ปฏิเสธก็fn2
จะเรียก ไม่มีการเปลี่ยนแปลงของผลลัพธ์ที่fn1
สามารถfn2
เรียกได้หรือในทางกลับกัน ดังนั้นหากคุณต้องการตรวจสอบให้แน่ใจว่ามีการเรียกตัวจัดการเพียงหนึ่งในสองตัวของคุณไม่ว่าจะเกิดอะไรขึ้นในตัวจัดการเองคุณก็สามารถp.then(fn1, fn2)
ใช้ได้