โดยพื้นฐานแล้วคุณกำลังถามว่าอะไรคือความแตกต่างระหว่างสองสิ่งนี้ ( 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)ใช้ได้