การดักจับข้อผิดพลาดใน Promise Chain ใน JavaScript

สมมติว่าเนื่องจากเหตุผลบางประการ Promise ของเรา สิ้นสุดลงด้วยข้อผิดพลาด:

javascriptlet promise = new Promise(function(resolve, reject) {
  setTimeout(function() {
    reject('error');
  }, 3000);
});

ในกรณีนี้ การทำงานของโค้ดจะเปลี่ยนไปที่ then ที่มีตัวจัดการข้อผิดพลาด หรือที่ catch แรก ขึ้นอยู่กับ ว่าอันไหนปรากฏขึ้นก่อน

นี่คือตัวอย่างของสถานการณ์แรก:

javascriptpromise.then(
  function(result) {
    return result + '1';
  }
).then(
  function(result) {
    return result + '2';
  },
  function(error) {
    // การทำงานจะเปลี่ยนมาที่นี่ทันที
  }
).then(
  function(result) {
    console.log(result);
  }
);

นี่คือตัวอย่างของสถานการณ์ที่สอง:

javascriptpromise.then(
  function(result) {
    return result + '1';
  }
).then(
  function(result) {
    return result + '2';
  }
).catch(
  function(error) {
    // การทำงานจะเปลี่ยนมาที่นี่ทันที
  }
).then(
  function(result) {
    console.log(result);
  }
);

ฟังก์ชันตัวจัดการมีสองทางเลือกในการดำเนินการ: หากมันสามารถจัดการกับสถานการณ์ผิดปกติได้ มันสามารถส่งกลับผลลัพธ์ผ่าน return และการทำงานจะดำเนินต่อไปตามห่วงโซ่ แต่ถ้ามันไม่สามารถจัดการข้อผิดพลาดได้ มันอาจจะ ไม่ส่งอะไรกลับมา หรือโยนข้อยกเว้น ผ่าน throw ในกรณีนี้การทำงาน จะเปลี่ยนไปยังตัวดักจับข้อผิดพลาดถัดไป (ใน then หรือ catch - สิ่งที่พบ ก่อน)

โดยทั่วไป ข้อผิดพลาดทั้งหมดของห่วงโซ่จะถูกดักจับ ในที่เดียว: catch จะถูกวางไว้ ที่ท้ายห่วงโซ่:

javascriptpromise.then(
  function(result) {
    return result + '1';
  }
).then(
  function(result) {
    return result + '2';
  }
).catch(
  function(error) {
    // จะมาที่นี่ในกรณีที่มีข้อผิดพลาด
  }
);

โดยข้อยกเว้นอาจเกิดขึ้นในตัว Promise เอง หรือถูกโยนผ่าน throw ในลิงก์ใด ๆ ของห่วงโซ่:

javascriptpromise.then(
  function(result) {
    return result + '1';
  }
).then(
  function(result) {
    if (ทุกอย่างดี) {
      return result + '2';
    } else {
      throw new Error('ข้อผิดพลาด'); // เปลี่ยนไปยังตัวดักจับที่ใกล้ที่สุด
    }
  }
)
.then(
  function(result) {
    return result + '3';
  }
).catch(
  function(error) {
    // ตัวดักจับที่ใกล้ที่สุด
  }
);

โปรดทราบว่า catch จำเป็นสำหรับ การวินิจฉัยข้อผิดพลาด: มันแก้ไขได้หรือไม่ หากข้อผิดพลาดแก้ไขได้ catch ควร ส่งการแก้ไขไปยัง then ถัดไป แต่ถ้าแก้ไขไม่ได้ (หรือ catch นี้ แค่ไม่รู้วิธีแก้) เราควร ไม่ส่งอะไรกลับมาหรือโยนข้อยกเว้น:

javascriptpromise.then(
  function(result) {
    return result + '1';
  }
).then(
  function(result) {
    return result + '2';
  }
).catch(
  function(error) {
    if (ข้อผิดพลาดแก้ไขได้) {
      return 'ข้อมูล'; // ส่งไปยัง then ถัดไป
    } else {
      // ไม่ส่งอะไรกลับมาหรือโยนข้อยกเว้น
    }
  }
).then(
  function(result) {
    // ที่นี่เราแก้ไขข้อผิดพลาด
  }
);