หลายครั้งที่เราเขียนโปรแกรมแล้วต้องการให้การทำงานของเราต้องทำอย่างหนึ่งเสร็จก่อนแล้วถึงจะทำอีกอย่างหนึ่ง แต่เนื่องด้วยบางครั้งเราต้องใช้คำสั่งที่การทำงานแบบ Asyncronous ซึ่งเป็นการทำงานแบบไม่รอกัน ดังนั้นเราจึงต้องบังคับให้โปรแกรมของเรารอกันก่อน ซึ่ง promise เป็นหนึ่งในทางเลือกที่สามารถมาแก้ปัญหานี้ได้ ซึ่งก่อนที่จะมาทำความรู้จักกับ promise เรามารู้จักกับ
Callback Function
การใช้ callback function แบบซ้อนเองก็เป็นหนึ่งในตัวเลือกในการแก้ไขปัญหานี้เช่นกัน โดยหลักการคือเมื่อฟังก์ชันหนึ่งเสร็จก็จะส่งข้อความไปบอกอีกฟังก์ชันหนึ่งให้ทำงานต่อนั่นเอง ยกตัวอย่างเช่นถ้าเรามีการทำงานว่าเมื่อเราทำ doFirst เสร็จก็จะทำ doSecond ต่อก็จะได้ว่า
function doFirst(callback) {
callback();
}
function doSecond(callback) {
callback();
}
doFirst(function() {
doSecond(function() {
console.log('success');
});
});
จากโค้ดข้างต้นเราจะเห็นว่าการใช้วิธี callback นั้นจะต้องนำฟังก์ชันมาซ้อนกันเข้าไปข้างในไปเรื่อยๆ การทำงานเพียงไม่กี่อย่างก็จะไม่ค่อยเห็นปัญหาเท่าไหร่ แต่ถ้าเราต้องให้ทำงานหลายขั้นตอนเยอะๆ อาจจะทำให้เกิดอาการมึนงงได้ แล้วยิ่งต้องใส่ รูปแบบ callback functionเข้าไปอีกยิ่งทำให้ดูยาก
Promise
การทำงานของ promise นั้นง่ายมาก ถ้าเราต้องการให้ทำงานฟังก์ชัน doSecond ต่อการฟังก์ชัน doFirst เราแค่ใช้ .then หลังจากการเรียกฟังก์ชัน doFirst แล้วใส่ฟังก์ชัน doSecond ลงไป แบบนี้
doFirst().then(doSecond).then(function() {
console.log('success');
});
โดยที่ฟังก์ชันของเราจะต้อง return promise โดยที่ promise จะต้องใส่พารามิเตอร์เป็น callback function ที่ใส่ fullfill และ reject ลงไป โดยที่การทำงานของfullfill จะเป็นการทำงานที่เป็นการทำงานปกติ และ reject จะเป็นเคสที่เราไม่ต้องการให้เกิดแบบนี้
function doFirst() {
return new Promise(function (fulfill, reject){
if (error) reject(error);
else fulfill(respond);
});
}
พอนำมาประกอบร่างกันก็จะได้แบบนี้
function doFirst() {
return new Promise(function (fulfill, reject){
if (error) reject(error);
else fulfill(respond);
});
}
function doSecond() {
return new Promise(function (fulfill, reject){
if (error) reject(error);
else fulfill(respond);
});
}
doFirst().then(doSecond).then(function() {
console.log('success');
});
จะเห็นได้ว่าตอนเรียกใช้ฟังก์ชัน ไม่ต้องใส่callbackฟังก์ชันเข้าไปแล้ว แถมการเขียนตอนเรียกก็สั้นและอ่านได้ง่ายกว่าแบบเก่ามาก