สิ่งสำคัญที่ต้องทำความเข้าใจที่นี่
ทั้งฟังก์ชันthenและcatchฟังก์ชันจะส่งคืนอ็อบเจ็กต์คำสัญญาใหม่
ไม่ว่าจะขว้างปาหรือปฏิเสธโดยชัดแจ้งจะย้ายสัญญาปัจจุบันไปสู่สถานะที่ถูกปฏิเสธ
เนื่องจากthenและcatchส่งคืนวัตถุสัญญาใหม่พวกเขาสามารถถูกล่ามโซ่ได้
หากคุณโยนหรือปฏิเสธภายในตัวจัดการคำสัญญา ( thenหรือcatch) จะถูกจัดการในตัวจัดการการปฏิเสธถัดไปตามเส้นทางการผูกมัด
ดังที่กล่าวไว้โดย jfriend00 ตัวจัดการthenและcatchตัวจัดการจะไม่ทำงานพร้อมกัน เมื่อตัวจัดการโยนมันจะจบลงทันที ดังนั้นสแต็กจะถูกคลายออกและข้อยกเว้นจะหายไป นั่นคือเหตุผลที่การโยนข้อยกเว้นปฏิเสธคำสัญญาปัจจุบัน
ในกรณีของคุณคุณกำลังปฏิเสธภายในdo1โดยการขว้างปาErrorสิ่งของ ตอนนี้สัญญาปัจจุบันจะอยู่ในสถานะปฏิเสธและการควบคุมจะถูกโอนไปยังตัวจัดการถัดไปซึ่งอยู่thenในกรณีของเรา
เนื่องจากthenตัวจัดการไม่มีตัวจัดการการปฏิเสธจึงdo2ไม่มีการดำเนินการใด ๆ คุณสามารถยืนยันได้โดยใช้console.logข้างใน catchเนื่องจากสัญญาปัจจุบันไม่ได้มีการจัดการปฏิเสธก็จะถูกปฏิเสธโดยมีมูลค่าการปฏิเสธจากสัญญาก่อนหน้านี้และการควบคุมจะถูกโอนไปจัดการต่อไปซึ่งเป็น
ในฐานะที่catchเป็นตัวจัดการการปฏิเสธเมื่อคุณทำconsole.log(err.stack);ภายในคุณจะเห็นการติดตามสแต็กข้อผิดพลาด ตอนนี้คุณกำลังขว้างErrorสิ่งของจากมันดังนั้นคำสัญญาที่ส่งกลับมาcatchจะอยู่ในสถานะปฏิเสธ
เนื่องจากคุณไม่ได้แนบตัวจัดการการปฏิเสธใด ๆ เข้ากับcatchเครื่องคุณจึงไม่สามารถสังเกตการปฏิเสธได้
คุณสามารถแยกโซ่และเข้าใจสิ่งนี้ได้ดีขึ้นเช่นนี้
var promise = do1().then(do2);
var promise1 = promise.catch(function (err) {
console.log("Promise", promise);
throw err;
});
promise1.catch(function (err) {
console.log("Promise1", promise1);
});
ผลลัพธ์ที่คุณจะได้รับจะเป็นอย่างไร
Promise Promise { <rejected> [Error: do1] }
Promise1 Promise { <rejected> [Error: do1] }
ภายในcatchตัวจัดการ 1 คุณจะได้รับค่าของpromiseวัตถุเป็นปฏิเสธ
ในทำนองเดียวกันสัญญาที่ส่งคืนโดยcatchตัวจัดการ 1 ก็ถูกปฏิเสธด้วยข้อผิดพลาดเดียวกันกับที่promiseถูกปฏิเสธและเรากำลังสังเกตมันในcatchตัวจัดการที่สอง
.catch(…)กลับมา