Skip to main content

เนื้อหาภาษาไทย / Thai content

System guide Content reviewed

การทำงานกับ Promises

บทความนี้กล่าวถึง Promises ใน JavaScript ซึ่งเป็นเครื่องมือสำคัญสำหรับการจัดการกับการทำงานที่ไม่พร้อมกัน (Asynchronous Programming) โดย Promises ช่วยให้โค้ดอ่าน...

การทำงานกับ Promises ใน JavaScript

ในโลกของการเขียนโปรแกรม JavaScript, การจัดการกับการทำงานที่ไม่พร้อมกัน (Asynchronous Programming) เป็นเรื่องที่หลีกเลี่ยงไม่ได้ โดยเฉพาะเมื่อเราต้องดึงข้อมูลจากเซิร์ฟเวอร์ หรือทำงานที่ใช้เวลานาน การทำงานเหล่านี้อาจทำให้โปรแกรมของเราหยุดชะงัก (Blocking) หากเราจัดการไม่ดี Promises เข้ามาช่วยแก้ปัญหานี้ ทำให้เราเขียนโค้ดที่อ่านง่ายและจัดการกับการทำงานที่ไม่พร้อมกันได้อย่างมีประสิทธิภาพ

Asynchronous Programming คืออะไร?

ก่อนที่จะไปถึง Promises เรามาทำความเข้าใจ Asynchronous Programming กันก่อน เมื่อเราเขียนโค้ดแบบ Synchronous โปรแกรมจะทำงานทีละบรรทัดตามลำดับ แต่ใน Asynchronous Programming โปรแกรมสามารถเริ่มทำงานบางอย่าง และดำเนินการต่อโดยไม่ต้องรอให้งานนั้นเสร็จสิ้น เมื่องานนั้นเสร็จสิ้นแล้ว โปรแกรมจะกลับมาจัดการกับผลลัพธ์ของงานนั้น ตัวอย่างเช่น การดึงข้อมูลจาก API:

console.log("เริ่มต้นการทำงาน");

setTimeout(() => {
  console.log("ดึงข้อมูลจาก API เสร็จสิ้น");
}, 2000); // รอ 2 วินาที

console.log("ทำงานอื่นๆ ต่อไป");

ในตัวอย่างนี้ `setTimeout` เป็นฟังก์ชัน Asynchronous ที่จะทำงานหลังจาก 2 วินาที โปรแกรมจะไม่รอให้ `setTimeout` ทำงานเสร็จ แต่จะพิมพ์ "ทำงานอื่นๆ ต่อไป" ทันที

Promises คืออะไร?

Promise คือ Object ที่เป็นตัวแทนของผลลัพธ์ของการทำงานที่ไม่พร้อมกัน ซึ่งอาจจะสำเร็จ (Resolved) หรือล้มเหลว (Rejected) Promise ช่วยให้เราจัดการกับการทำงานที่ไม่พร้อมกันได้อย่างเป็นระเบียบ โดยใช้ `.then()` เพื่อจัดการกับผลลัพธ์เมื่อสำเร็จ และ `.catch()` เพื่อจัดการกับข้อผิดพลาดเมื่อล้มเหลว

การสร้าง Promise

เราสามารถสร้าง Promise ได้โดยใช้ Constructor `new Promise()` Constructor นี้รับ Function ที่มี Parameter สองตัวคือ `resolve` และ `reject`:

  • `resolve`: Function ที่ถูกเรียกเมื่อการทำงานสำเร็จ
  • `reject`: Function ที่ถูกเรียกเมื่อการทำงานล้มเหลว

ตัวอย่างการสร้าง Promise:

const myPromise = new Promise((resolve, reject) => {
  // ทำงานบางอย่างที่อาจสำเร็จหรือล้มเหลว
  const success = true; // หรือ false

  if (success) {
    resolve("การทำงานสำเร็จ!");
  } else {
    reject("การทำงานล้มเหลว!");
  }
});

ในตัวอย่างนี้ ถ้า `success` เป็น `true` เราจะเรียก `resolve` พร้อมกับส่งค่า "การทำงานสำเร็จ!" ไปด้วย ถ้า `success` เป็น `false` เราจะเรียก `reject` พร้อมกับส่งค่า "การทำงานล้มเหลว!" ไปด้วย

สถานะของ Promise

Promise มีสถานะ 3 สถานะ:

  • Pending: สถานะเริ่มต้น, ยังไม่สำเร็จหรือล้มเหลว
  • Resolved (Fulfilled): การทำงานสำเร็จ
  • Rejected: การทำงานล้มเหลว

เมื่อ Promise เปลี่ยนสถานะจาก Pending ไปเป็น Resolved หรือ Rejected สถานะจะไม่สามารถเปลี่ยนแปลงได้อีก

การใช้ .then() และ .catch()

เราใช้ `.then()` เพื่อจัดการกับผลลัพธ์เมื่อ Promise เปลี่ยนสถานะเป็น Resolved และใช้ `.catch()` เพื่อจัดการกับข้อผิดพลาดเมื่อ Promise เปลี่ยนสถานะเป็น Rejected

ตัวอย่างการใช้งาน `.then()` และ `.catch()`:

myPromise
  .then((result) => {
    // จัดการกับผลลัพธ์เมื่อสำเร็จ
    console.log("ผลลัพธ์:", result); // ผลลัพธ์: การทำงานสำเร็จ!
  })
  .catch((error) => {
    // จัดการกับข้อผิดพลาดเมื่อล้มเหลว
    console.error("ข้อผิดพลาด:", error); // ข้อผิดพลาด: การทำงานล้มเหลว! (ถ้า success เป็น false)
  });

`.then()` รับ Function เป็น Parameter ซึ่ง Function นี้จะถูกเรียกเมื่อ Promise เปลี่ยนสถานะเป็น Resolved และได้รับค่าที่ส่งมาจาก `resolve` เป็น Argument

`.catch()` รับ Function เป็น Parameter ซึ่ง Function นี้จะถูกเรียกเมื่อ Promise เปลี่ยนสถานะเป็น Rejected และได้รับค่าที่ส่งมาจาก `reject` เป็น Argument

Chaining Promises

เราสามารถ Chain Promises ได้ โดยการ Return Promise ใหม่จาก `.then()` Function:

const fetchData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const data = { id: 1, name: "Example Data" };
      resolve(data);
    }, 1000);
  });
};

const processData = (data) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const processedData = { ...data, processed: true };
      resolve(processedData);
    }, 500);
  });
};

fetchData()
  .then((data) => {
    console.log("Data fetched:", data);
    return processData(data); // Return Promise ใหม่
  })
  .then((processedData) => {
    console.log("Processed data:", processedData);
  })
  .catch((error) => {
    console.error("Error:", error);
  });

ในตัวอย่างนี้ `fetchData` และ `processData` ต่างก็ Return Promise เมื่อ `fetchData` สำเร็จ เราจะเรียก `processData` และ Return Promise ที่ได้จาก `processData` ไปยัง `.then()` ตัวถัดไป ทำให้เราสามารถทำงานหลายขั้นตอนต่อเนื่องกันได้อย่างเป็นระเบียบ

การจัดการ Error ใน Promise Chain

ถ้ามี Error เกิดขึ้นใน Promise Chain, `.catch()` ตัวแรกที่เจอจะถูกเรียก:

const fetchDataWithError = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject("เกิดข้อผิดพลาดในการดึงข้อมูล");
    }, 1000);
  });
};

fetchDataWithError()
  .then((data) => {
    console.log("Data fetched:", data);
  })
  .then((processedData) => {
    console.log("Processed data:", processedData);
  })
  .catch((error) => {
    console.error("Error:", error); // Error: เกิดข้อผิดพลาดในการดึงข้อมูล
  });

ในตัวอย่างนี้ `fetchDataWithError` จะ Reject Promise ด้วย Error message ดังนั้น `.catch()` จะถูกเรียกทันที และ `.then()` ทั้งสองตัวจะไม่ถูกเรียก

Promise.all()

`Promise.all()` เป็น Static Method ที่รับ Array ของ Promises และ Return Promise ใหม่ที่ Resolved เมื่อ Promises ทั้งหมดใน Array Resolved หรือ Rejected เมื่อมี Promise ใด Promise หนึ่งใน Array Rejected:

const promise1 = Promise.resolve(1);
const promise2 = new Promise((resolve) => setTimeout(() => resolve(2), 200));
const promise3 = new Promise((resolve) => setTimeout(() => resolve(3), 100));

Promise.all([promise1, promise2, promise3])
  .then((values) => {
    console.log(values); // [1, 2, 3]
  })
  .catch((error) => {
    console.error("Error:", error);
  });

ในตัวอย่างนี้ `Promise.all()` จะรอให้ `promise1`, `promise2`, และ `promise3` Resolved แล้ว Return Array ของผลลัพธ์

Promise.race()

`Promise.race()` เป็น Static Method ที่รับ Array ของ Promises และ Return Promise ใหม่ที่ Resolved หรือ Rejected ตาม Promise ตัวแรกที่ Resolved หรือ Rejected:

const promise4 = new Promise((resolve) => setTimeout(() => resolve(4), 500));
const promise5 = new Promise((resolve) => setTimeout(() => resolve(5), 100));

Promise.race([promise4, promise5])
  .then((value) => {
    console.log(value); // 5
  })
  .catch((error) => {
    console.error("Error:", error);
  });

ในตัวอย่างนี้ `promise5` Resolved ก่อน `promise4` ดังนั้น `Promise.race()` จะ Resolved ด้วยค่า 5

สรุป

Promises เป็นเครื่องมือที่สำคัญในการจัดการกับการทำงานที่ไม่พร้อมกันใน JavaScript ช่วยให้โค้ดของเราอ่านง่ายและจัดการกับ Error ได้อย่างมีประสิทธิภาพ เราได้เรียนรู้เกี่ยวกับการสร้าง Promise, สถานะของ Promise, การใช้ `.then()` และ `.catch()`, การ Chain Promises, และการใช้ `Promise.all()` และ `Promise.race()` ในบทความถัดไป เราจะมาเรียนรู้เกี่ยวกับ `async/await` ซึ่งเป็น Syntax ที่ช่วยให้การเขียนโค้ด Asynchronous ง่ายยิ่งขึ้นไปอีก

Office.in.th Custom Service

Want to build or adapt a system from this structure?

Office.in.th designs and develops enterprise web applications, API integrations, and public- and private-sector management systems, with long-term support.

See our software development service