Sharing is caring!

พรอมิส (Promise)

ES6 จะมี Object ที่เรียกว่า “พรอมิส” (Promise) เป็นตัวช่วยให้การเขียนโปรแกรมแบบ Asynchronous ทำให้ Source Code ของคุณจัดการได้ง่าย และเป็นระเบียบดียิ่งขึ้น ปัจจุบัน Browser ค่ายดังอย่าง Firefox ,Google Chome ,Safari Support บ้างแล้วแต่จะมีปัญหากับ Browser บางค่ายจะยังไม่ Support อยากใช้จำเป็นต้องผ่านการ compile ผ่าน Compiler ยอดฮิต อย่าง Bebel JS ให้เป็น ES5 ซะก่อน (ติดตามการพัฒนาได้จาก ECMAScript compatibility)

let promise = new Promise( executor );

ตัวอย่างการสร้าง Promise Object ในส่วนของ executor คือค่า function callback ธรรมดาทั่วไปนั้นเอง

function executor_function (resolve ,reject){
    // TODO
}

การประกาศฟังก์ชั่น executor_function จะต้องมี parameter ที่จำเป็น 2 ตัว คือ Resolve , Reject (จะตั้งชื่อเป็นอะไรก็ได้) สนใจแค่ตำแหน่งลำดับ

เนื่องจากคำว่า Promise มีความหมายว่า “สัญญา” ด้วยเหตุผลนี้ในทาง Javascript จะหมายถึงตัวแทน Object ที่ยังทำงานไม่เสร็จแต่ให้คำมั่นว่าจะทำงานเสร็จในอนาคตนั่นเอง




สถานะของ พรอมิส (Promise)

เนื่องจากการทำงานใน Object ที่เป็น Function Callback นั้นผลของการทำงานอาจจะดำเนินการสำเร็จ หรือ ไม่สำเร็จ ดังนั้น Promise เองก็จะมีสถานะที่แตกต่างกันไป โดยแบ่งออกเป็น 3 สถานะ ดังต่อไปนี้

  1. สถานะ Pending (รอก่อน) หมายถึง Promise ยังทำงานไม่เสร็จ
  2. สถานะ Fulfilled (สมหวัง) หมายถึง Promise ที่ทำงานเสร็จแล้ว
  3. สถานะ Rejected (ล้มเลิกไป) หมายถึง Promise ที่ทำงานไม่สำเร็จ ล้มเหลว หรือเกิด Error ระหว่างการทำงาน

Fulfilled และ Rejected จะเรียกรวมกันว่าสถานะ settled (ตัดสินใจ)

เมธอด then()

function callback executor จะมีการประกาศ parameter ไว้ 2 ตัว

function executor(resolve,reject){
    // source code 

    if(success){
       resolve(value); // Line a
    }

    if(failed){
       reject(reason) // line b
    }
}

var promise = new Promise(executor);

promise.then(function lineA(value){
    /*source code */
},function lineB(reason){
    /*source code */
});

เมื่อเรียกใช้งาน function executor ซึ่งเป็นการทำงานแบบ Asynchronous โดย Logic ของโปรแกรม จะ expect ผลเป็น success และ failed ถ้า success จะ return ค่า value ออกไป ผ่าน resolve() แต่ถ้าเป็น failed จะ return ค่า reason ออกไปผ่าน reject() ออกไป โดยที่ .then จะมี parameter function callback 2 function คือ lineA และ lineB หน้าที่ของ function lineA คือจะทำก็ต่อเมื่อค่าที่ได้จาก object promise เป็นการทำงานที่ fulfilled (สำเร็จ) และ function lineB จะทำก็ต่อเมื่อกรณีการทำงานเกิด failed ,error (ไม่สำเร็จ)

เมธอด catch()

เสมือนการเรียกใช้งาน .then ที่เป็นเหตุการณ์ที่ไม่สำเร็จเท่านั้น

promise.catch(function(reason){
      /* rejected */
});

promise.then(null,function(reason){
      /*  reason*/
});

ทั้ง 2 ทำหน้าที่เหมือนกัน
เรียก then() แบบต่อเนื่อง

ปกติเมื่อเราเรียกเมธอด .then() มันก็จะ return Promise ออกมาเสมอโดยไม่ต้องเขียน คำสั่ง return อะไรเลย เราจึงสามารถเรียก .then() ได้อย่างต่อเนื่อง

let p1 = new Promise(function(resolve,reject){
     resolve("success");
});

let p2 = p1.then(function(value){
    console.log('Promise : ',value);
});

let p3 = p2.then(function(){
    console.log('Finish');
});

/* result 
"Promise : success"
"Finish"
*/




ดักจับ error แบบต่อเนื่อง
let promise = new Promise(function(resolve,reject){
     throw new Error('error1');
});

promise.catch(function(error){
     console.log("catch1: ",error.message);
     throw new Error('error2');
}).catch(function(error){
     console.log("catch2: ",error.message);
     throw new Error('error3');
}).catch(function(error){
     console.log("catch3: ",error.message);
});

/* result
"catch1: error1"
"catch1: error2"
"catch1: error3" */
Promise.all()

การเรียกใช้ Promise หลายตัวพร้อมกันก็สามารถทำได้

let p1 = Promise.resolve('Promise1');
let p2 = Promise.resolve('Promise2');
let p3 = Promise.resolve('Promise3');

let p4 = new Promise.all([p1,p2,p3]);

p4.then(function(value){
     console.log(value);
});


/* result 
["Promise1","Promise2","Promise3"] */

# เครดิตจากหนังสือ “พัฒนาเว็บแอปพิเคชั่นด้วย Javascript” โดย คุณ จตุรพัชร์ พัฒนทรงศิวิไล ขอขอบคุณครับสำหรับเนื้อหาสำหรับบทความนี้