Javascript ES6 - Promise
Promise เป็นฟีเจอร์ใหม่ที่เพิ่มขึ้นมาใน ECMAScript 6 เพื่อช่วยทำงานแบบ asynchronous ที่ทำหน้าที่เหมือนคำสัญญาในภาษาโปรแกรม เมื่อทำงานเสร็จแล้วจะคืนผลออกมา 2 ทาง คือ ทำตามสัญญา(Fulfilled/Resolved) หรือ ผิดสัญญา(Reject) และสามารถเก็บข้อมูลที่ได้ไปใช้ต่อ
ก่อนหน้านี้ เราจะต้องส่ง callback เข้าไปใน function เพื่อให้ภายใน function เรียกใช้
var callback1 = function () {…};
var callback2 = function () {…};var doSomething = function (success, fail) {
…
isSuccess? success(): fail();
}
doSomething(callback1, callback2);
ถ้าเราเปลี่ยนมาเป็น Promise หล่ะ ทาง Object จาก Promise จะสามารถเพิ่ม callback เข้าไปได้
var callback1 = function () {…};
var callback2 = function () {…};var doSomething = function () {
…
return new Promise(function(resolve, reject){…});
}
doSomething().then(callback1)
.catch(callback2);
new Promise()
Promise จะเริ่มทำงานทันทีที่มีการประกาศ โดย Promise มีสถานะอยู่ 3 สถานะ คือ
- pending: สถานะเริ่มเมื่อ Promise ยังทำงานไม่เสร็จ
- fulfilled/resolved: สถานะทำงานเสร็จและ สำเร็จ
- rejected: สถานะการทำงานผิดพลาด
การประกาศ Promise จะต้องส่ง function เข้าไปทุกครั้ง โดย function นี้จะรับค่า 2 ค่า คือ function resolve และ reject
new Promise(function(resolve, reject){…});
โดย resolve จะเป็นการประกาศว่า Promise นี้ สำเร็จแล้วจะเปลี่ยนสถานะของตัวเองเป็น fulfilled/resolved ทันที resolve จะรับค่าได้ 1 ค่า คือ value ข้อมูลที่ถูกต้อง จะถูกส่งไปยัง callback ในสถานะ resolved
resolve(value);
ส่วน reject จะตรงข้ามกับ resolve คือ ทำงานผิดพลาด และเปลี่ยนสถานะเป็น rejected และ reject สามารถรับค่าได้ 1 ค่าเหมือนกัน แทนเหตุผล(reason)ที่โดน reject
reject(reason);
นอกจากนี้ การ throw error ก็จะเปลี่ยน Promise ให้เป็น rejected ได้เช่นกัน โดย Error ที่ throw ออกไปจะเป็น reason ด้วย
throw new Error(reason)
การรับผลจาก Promise
จากผลของ Promise เราจะสามารถเพิ่ม callback ลงไปใน Promise ได้ 2 แบบ คือ callback ในสถานะ resolved และ callback ในสถานะ rejected
p.then(onResolved[, onRejected]);
p.then(function(value) {
// resolution
}, function(reason) {
// rejection
});
then นั้นรับ callback ได้ ทั้ง 2 ทาง โดย onRejected เป็น Optional ซึ่งถามผลของ Promise เป็น rejected จะข้าม then นี้ไปทันที
การคืนค่าใดก็ตามของทั้ง onResolved และ onRejected จะทำให้ผลเป็น resolved เสมอ และค่าที่คือจะเป็น value ต่อไป
การ Throw error ยังทำงานเหมือนใน Promise() คือ ผลเป็น rejected และ Error เป็น reason
p.catch(onRejected);
p.catch(function(reason) {
// rejection
});
catch จะรับ callback เฉพาะ onRejected เท่านั้น promise ที่เป็น resolved จะข้าม catch นี้ไป
เช่นเดียวกับ then การคืนค่า และการ throw error จะให้ผลเหมือนกัน
การรับผลของ Promise จะทำเป็นลำดับ และส่งผลของ then หรือ catch ของอันก่อนหน้าไปยังอันต่อๆไป
p.then(onResolved1)
.then(onResolved2, onReject2)
.then(onResolved3)
.catch(onReject4);
สุดท้ายแล้ว ที่จริง การทำงานแบบ Promise นั้น มีมาก่อน ES6 เสียอีกจาก library อย่าง jQuery หรือ Angular แต่ ES6 ได้นำหลักการเหล่านี้ มาทำขึ้นเป็นมาตรฐานให้ เราได้ใช้กันง่ายขึ้น