สิ่งสำคัญที่ต้องทำความเข้าใจที่นี่
ทั้งฟังก์ชัน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(…)
กลับมา