PlusMagi's Blog By Pitt Phunsanit Backend TypeScript: การใช้งาน Callback

TypeScript: การใช้งาน Callback

ในโลกของการพัฒนาซอฟต์แวร์สมัยใหม่ การจัดการกับงานที่ต้องใช้เวลา (Asynchronous Operations) เช่น การเรียกใช้ API หรือการดึงข้อมูลจากฐานข้อมูล (Database Query) เป็นสิ่งที่หลีกเลี่ยงไม่ได้ เมื่อโค้ดของเราต้องรอผลลัพธ์จากภายนอก การใช้กลไกที่เหมาะสมจึงสำคัญอย่างยิ่ง บทบาทของ Callback Function คือหัวใจสำคัญในการจัดการลำดับการทำงานเหล่านี้

เข้าใจแนวคิด Callback Function

Callback function คือฟังก์ชันที่เราส่งเป็นอาร์กิวเมนต์ให้กับฟังก์ชันอื่น เพื่อให้ฟังก์ชันนั้นถูกเรียกใช้งานในภายหลัง เมื่อกระบวนการหลักได้ดำเนินการเสร็จสิ้น ไม่ว่าจะสำเร็จหรือไม่ก็ตาม ในเชิงของ Event-Driven Programming, Callback ทำหน้าที่เป็นตัวกำหนด ‘สิ่งที่ควรทำต่อไป’ หลังจากที่เหตุการณ์บางอย่างเกิดขึ้น นี่คือกลไกพื้นฐานที่ทำให้ระบบสามารถตอบสนองต่อเหตุการณ์ที่เกิดขึ้นตามเวลาได้

TypeScript: เพิ่มความปลอดภัยให้ Callback

หากเราใช้ JavaScript บริสุทธิ์ การจัดการ Callback นั้นทรงพลัง แต่ก็มาพร้อมกับความเสี่ยงด้าน Type Safety ที่อาจทำให้เกิดบั๊กที่ตรวจจับได้ยากในขณะ Runtime TypeScript จึงเข้ามาแก้ไขปัญหานี้ด้วยการบังคับประเภทข้อมูล (Type Enforcement) ให้กับทั้งตัว Callback และค่า Argument ทั้งหมด ทำให้เราสามารถมั่นใจได้ตั้งแต่ Compile Time ว่าฟังก์ชันที่รับเข้ามามี Signature ที่ถูกต้องตามที่ระบบคาดหวัง ซึ่งเป็นสิ่งสำคัญอย่างยิ่งเมื่อต้องทำงานกับข้อมูลภายนอก เช่น การเชื่อมต่อ PostgreSQL

ตัวอย่าง: การจำลองการ Query ข้อมูลจาก Database

สมมติว่าเรากำลังเขียนฟังก์ชันที่จำลองการดึงข้อมูลผู้ใช้จากฐานข้อมูล (ซึ่งในความเป็นจริงจะใช้ไลบรารีเช่น pg) เราต้องมั่นใจว่าเมื่อการ Query สำเร็จหรือล้มเหลว Callback จะถูกเรียกใช้ด้วยรูปแบบที่ถูกต้อง

TypeScript

// 1. กำหนด Type สำหรับ Callback Function (Error, Result) => void
type DbCallback<T> = (error: Error | null, data: T | null) => void;

/**
 * ฟังก์ชันจำลองการดึงข้อมูลจาก DB
 * @param query คำสั่ง SQL ที่จะรัน
 * @param callback ฟังก์ชันที่จะถูกเรียกเมื่อ Query เสร็จสิ้น
 */
function fetchUserData(query: string, callback: DbCallback<string>): void {
    // จำลองการทำงานแบบ Asynchronous (เช่น การรอผลลัพธ์จาก PostgreSQL)
    setTimeout(() => {
        if (query.includes('error')) {
            // กรณีเกิดข้อผิดพลาด
            callback(new Error("Connection failed"), null);
        } else {
            // กรณีสำเร็จ (จำลองการได้ผลลัพธ์เป็นสตริง)
            const result: string = "1,2,3";
            callback(null, result);
        }
    }, 500);
}

// การใช้งาน: การส่ง Callback เข้าไป
fetchUserData("SELECT * FROM users WHERE id = 1", (err, data) => {
    if (err) {
        console.error("Database Error:", err.message);
    } else if (data) {
        console.log("Success! Data retrieved: " + data);
    }
});

บทสรุป

การใช้ TypeScript ร่วมกับ Callback Function ไม่เพียงแต่ช่วยให้โค้ดของเราสามารถจัดการกับ Asynchronous Operations ได้อย่างมีประสิทธิภาพเท่านั้น แต่ยังเพิ่มความมั่นใจในความถูกต้องของโค้ด (Type Safety) ได้อย่างมาก การทำความเข้าใจรูปแบบนี้จึงเป็นทักษะสำคัญสำหรับ Senior Developer ที่ต้องทำงานกับระบบที่ต้องพึ่งพาการสื่อสารกับแหล่งข้อมูลภายนอกอย่างฐานข้อมูล PostgreSQL หรือ API อื่นๆ เสมอ