การเขียน asynchronous code ใน JavaScript ก่อนหน้านี้ยุ่งยาก ต้องใช้ callback functions หลายชั้น ทำให้โค้ดอ่านยาก ES6 นำเสนอ Promises เพื่อเขียน asynchronous code ได้อย่างมีประสิทธิภาพ
Promise คืออะไร?
Promise คืออ็อบเจ็กต์ที่คืนค่าตอบสนองที่เราต้องการในอนาคต คล้ายกับคำสัญญาในชีวิตจริง: สัญญาว่าจะทำบางอย่างในอนาคต ไม่ได้ทำทันที
Promise มี 3 สถานะ:
- Pending: ยังไม่เสร็จสิ้น
- Fulfilled: เสร็จสิ้นสำเร็จ (resolved)
- Rejected: ล้มเหลว ไม่คืนค่าได้
เมื่อสร้าง promise จะอยู่ในสถานะ pending จนกว่าจะได้รับการตอบสนอง แล้วจึงเปลี่ยนเป็น fulfilled หรือ rejected
สร้าง JavaScript Promise
สร้าง Promise object ด้วย constructor:
new Promise((resolve, reject) => {
// โค้ดของคุณ
});
รับ 2 arguments: ฟังก์ชันจัดการ success (resolve) และฟังก์ชันจัดการ failure (reject) ควรมีเงื่อนไข if ตัดสินใจว่า resolve หรือ reject
new Promise((resolve, reject) => {
if (condition) {
resolve();
} else {
reject();
}
});
ตัวอย่าง: คืนค่าชื่อหลัง 3 วินาที
let returnName = new Promise((resolve, reject) => {
let name;
setTimeout(() => {
name = "Cinnamon";
if (name === "Cinnamon") {
resolve(name);
} else {
reject("This promise has failed.");
}
}, 3000);
});
โค้ดนี้รอ 3 วินาที (3000 ms) ถ้า name เป็น "Cinnamon" จะ resolve คืนค่าชื่อ มิฉะนั้น reject
then() และ catch() กับ Promises
เรียกใช้ promise ด้วย then():
returnName.then(data => {
console.log(data);
});
then() เรียกเมื่อ promise resolved สำเร็จ พิมพ์ค่า data ที่ได้จาก promise
Promise Chaining
ใช้ then() หลายตัวติดกัน:
returnName
.then(data => { console.log(data); })
.then(() => { console.log("This function is over!"); });
ผลลัพธ์:
Cinnamon This function is over.
จัดการ Rejection ด้วย catch()
returnName
.then(data => { console.log(data); })
.catch(error => { console.log(error); });
สำคัญ: ไม่ควรใส่ semicolon หลัง then() ถ้าจะต่อ catch() ไม่งั้น JavaScript จะคิดว่าเป็น statement แยกกันและ error
finally() กับ Promises
ถ้าต้องการรันโค้ดหลัง promise เสร็จ ไม่ว่าจะสำเร็จหรือล้มเหลว ใช้ finally():
returnName
.then(data => { console.log(data); })
.catch(error => { console.log(error); })
.finally(() => { console.log("The returnName promise has been executed."); });
ผลลัพธ์ (เมื่อสำเร็จ):
Cinnamon The returnName promise has been executed.
สรุป
JavaScript Promises ช่วยเขียน asynchronous code ให้สะอาด บทความนี้ครอบคลุมพื้นฐาน ขั้นต่อไปคือลองเขียน promises เอง เช่น สร้าง promise ที่ทำ web request ด้วย fetch() API และจัดการทั้ง success และ error cases
ห้องเรียนรู้เพิ่มเติม: JavaScript async functions ซึ่งใช้ร่วมกับ Promises บ่อย