TypeScript Academy · บทเรียน

การเขียนโปรแกรมแบบ Railway-Oriented

เชื่อมการดำเนินการที่อาจล้มเหลวโดยไม่ต้องใช้ try/catch

บทเรียน 4 จาก 413 ขั้นตอน

การเขียนโปรแกรมแบบ Railway-Oriented เป็นบทเรียน TypeScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน TypeScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน

อุปมาทางรถไฟ

การเขียนโปรแกรมแบบทางรถไฟ เปรียบการคำนวณเป็นรางคู่ขนานสองราง ได้แก่ รางความสำเร็จและรางความล้มเหลว เมื่อเปลี่ยนไปสู่รางความล้มเหลวแล้ว ก็จะอยู่ที่นั่นต่อและข้ามขั้นตอนที่เหลือ

การเชื่อมฟังก์ชัน Result

แต่ละขั้นตอนรับค่าเข้ามาและคืนค่าเป็น Result เราต้องการเชื่อมขั้นตอนเหล่านี้เพื่อให้ความล้มเหลวแรกหยุดการทำงานต่อของสาย และถูกส่งต่อไปจนถึงจุดสิ้นสุด

type Result<T, E> = { ok: true; value: T } | { ok: false; error: E };
const ok = <T>(value: T): Result<T, never> => ({ ok: true, value });
const err = <E>(error: E): Result<never, E> => ({ ok: false, error });

map: แปลงค่าความสำเร็จ

map ใช้ฟังก์ชันปกติกับค่าเมื่อ Result อยู่ในสถานะสำเร็จ และส่งต่อความล้มเหลวโดยไม่เปลี่ยนแปลง วิธีนี้ยังคงอยู่บนรางความสำเร็จ

function map<T, U, E>(r: Result<T, E>, f: (t: T) => U): Result<U, E> {
  return r.ok ? ok(f(r.value)) : r;
}
console.log(map(ok(2), n => n + 1)); // { ok: true, value: 3 }

flatMap: เชื่อมขั้นตอนที่อาจล้มเหลว

เมื่อขั้นตอนถัดไปคืนค่าเป็น Result ด้วย ให้ใช้ flatMap (เรียกอีกอย่างว่า andThen) วิธีนี้หลีกเลี่ยงการซ้อน Result และหยุดการทำงานต่อเมื่อเกิดความล้มเหลว

function flatMap<T, U, E>(r: Result<T, E>, f: (t: T) => Result<U, E>): Result<U, E> {
  return r.ok ? f(r.value) : r;
}

ทำไมจึงไม่ใช้ flatMap แทน map

หากใช้ map กับฟังก์ชันที่คืนค่าเป็น Result คุณจะได้ Result<Result<U,E>,E> ส่วน flatMap จะแผ่โครงสร้างซ้อนออกหนึ่งระดับ ทำให้เหลือ Result เดียว

หยุดการทำงานต่อเมื่อพบข้อผิดพลาดแรก

ทันทีที่ขั้นตอนหนึ่งคืนค่า err การเรียกใช้ flatMap ในขั้นตอนถัดไปทุกครั้งจะส่งค่านั้นต่อไปโดยไม่เปลี่ยนแปลง ขั้นตอนที่เหลือจะไม่ทำงาน เช่นเดียวกับการเปลี่ยนไปสู่รางความล้มเหลว

const start = err("boom") as Result<number, string>;
const out = flatMap(start, n => ok(n + 1));
console.log(out); // { ok: false, error: "boom" }

การสร้างสายงาน

ประกอบขั้นตอนการตรวจสอบความถูกต้อง โดยแต่ละขั้นตอนคืนค่าเป็น Result ความล้มเหลวแรกจะกลายเป็นผลลัพธ์ของสายงาน หากทุกขั้นตอนผ่าน ค่าความสำเร็จจะไหลไปจนถึงจุดสิ้นสุด

function parseNum(s: string): Result<number, string> {
  const n = Number(s);
  return Number.isNaN(n) ? err("not a number") : ok(n);
}
function positive(n: number): Result<number, string> {
  return n > 0 ? ok(n) : err("must be positive");
}

การเรียกใช้สายงาน

การเชื่อม flatMap จะส่งค่าผ่านแต่ละขั้นตอนที่อาจล้มเหลว หากเกิดความล้มเหลวที่ใดก็ตาม สายจะหยุดลงและแสดงข้อผิดพลาดนั้น

const good = flatMap(parseNum("5"), positive);
console.log(good); // { ok: true, value: 5 }
const bad = flatMap(parseNum("-3"), positive);
console.log(bad); // { ok: false, error: "must be positive" }

การรวม map และ flatMap

ใช้ flatMap กับขั้นตอนที่อาจล้มเหลว และใช้ map กับการแปลงค่าบริสุทธิ์ ทั้งสองอย่างร่วมกันทำให้เส้นทางปกติเป็นเส้นตรง และจัดการข้อผิดพลาดโดยอัตโนมัติ

const result = map(flatMap(parseNum("10"), positive), n => n * 2);
console.log(result); // { ok: true, value: 20 }

ไม่ต้องใช้ try/catch

สายงานทั้งหมดสื่อความสำเร็จและความล้มเหลวผ่านค่า จึงไม่ต้องใช้ try/catch และชนิดข้อมูลของทุกขั้นตอนจะทำให้เส้นทางข้อผิดพลาดชัดเจนและหลีกเลี่ยงไม่ได้

เหตุผลที่รองรับการขยาย

โค้ดแบบทางรถไฟช่วยให้กระบวนการทำงานที่ซับซ้อนยังอ่านง่าย แต่ละขั้นตอนมีขนาดเล็กและบริสุทธิ์ ข้อผิดพลาดถูกส่งต่อโดยอัตโนมัติ และการเพิ่มขั้นตอนไม่ทำให้การจัดการข้อผิดพลาดเดิมซับซ้อนขึ้น

ตรวจสอบความเข้าใจ

ตรวจสอบความเข้าใจบทเรียนนี้อย่างรวดเร็ว

ทบทวน

การเขียนโปรแกรมแบบทางรถไฟ เชื่อมขั้นตอนที่คืนค่าเป็น Result ด้วย map (แปลงค่าความสำเร็จ) และ flatMap/andThen (เชื่อมขั้นตอนที่อาจล้มเหลวและแผ่ Result ที่ซ้อนกัน) err แรกจะหยุดขั้นตอนที่เหลือ และส่งต่อไปจนถึงจุดสิ้นสุดโดยไม่ต้องใช้ try/catch

เริ่มต้นได้ฟรี

เรียนรู้ TypeScript ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
101
บทเรียน
352

คำถามที่พบบ่อย

บทเรียน “การเขียนโปรแกรมแบบ Railway-Oriented” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การเขียนโปรแกรมแบบ Railway-Oriented” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส TypeScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การเขียนโปรแกรมแบบ Railway-Oriented”

เชื่อมการดำเนินการที่อาจล้มเหลวโดยไม่ต้องใช้ try/catch คุณปฏิบัติ TypeScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน TypeScript Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน TypeScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “การเขียนโปรแกรมแบบ Railway-Oriented” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน TypeScript Academy นี้ได้ไหม

ได้ บทเรียน TypeScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ปัญหาของการโยนข้อผิดพลาด
  2. การจำลองชนิดข้อมูล Result
  3. ชนิดข้อมูล Option และ Maybe
  4. การเขียนโปรแกรมแบบ Railway-Oriented
← กลับไปที่ TypeScript Academy