Narupon Tee Srisantitham
Konoe
Published in
3 min readJan 26, 2017

--

Promise ใน Javascript

Promise

คือ object หนึ่งที่มีใน native javascript เป็นตัวช่วยเราให้สามารถเขียนโปรแกรมแบบ asynchronous ได้สะดวกมากขึ้น ลดปัญหาการ call back ที่ดูยากไม่เป็นระเบียบ ลองมาดูกันครับว่ามันจะช่วยเราได้ยังไงกันบ้าง

ก่อนจะพูดถึง Promise ก็ต้องรู้จักกับการเขียนโปรแกรมแบบ asynchronous กันก่อน การเขียนโปรแกรมแบบ asynchronous ก็จะตรงข้ามกับการเขียนโปรแกรมแบบ synchronous คือการเขียนโปรแกรมแบบเป็นลำดับขั้น หรือการไล่ code จากบนลงล่างนั่นเอง เพราะฉะนั้น asynchronous ก็คือการเขียนโปรแกรมแบบไม่ไล่ code จากบนลงล่างเสมอไป ดูได้ดังตัวอย่าง code ต่อไปนี้ครับ

var img1 = document.querySelector('.img-1');

img1.addEventListener('mouseover', function() {
// ทำงาน 1
});

img1.addEventListener('click', function() {
// ทำงาน 2
});

จาก code ตัวอย่าง คือการสร้าง listener เพื่อดักการทำงานจาก user การทำงานที่ 1 คือทำเมื่อมีการวาง mouse บน object การทำงานที่ 2 ทำเมื่อมีการ click object จะเห็นได้ว่าทั้ง 2 การทำงานเป็นแบบ asynchronous เพราะทั้ง 2 งานไม่ได้ไล่ลำดับกัน อาจทำงาน 2 ก่อนที่จะทำงาน 1 ก็ได้ แล้วแต่ user จะทำ event ไหนก่อน

ตัวอย่างที่ผ่านมาคือกรณีที่ code ไม่มีความซับซ้อนทำให้มองไม่เห็นปัญหา แต่ถ้าลองดูตัวอย่างต่อไปอาจทำให้เห็นภาพมากขึ้นว่าทำไม Promise ถึงต้องเข้ามาช่วยในการทำงานของเรา

function get(url, callback) {
// Do the usual XHR stuff
var req = new XMLHttpRequest();
req.open('GET', url);

req.onload = function() {
// This is called even on 404 etc
// so check the status
if (req.status == 200) {
callback ({ 'status': 'success', 'data': req.response})
}
else {
// Otherwise reject with the status text
callback ({ 'status': 'fail', 'data': req.statusText})
}
};

// Handle network errors
req.onerror = function() {
callback ({ 'status': 'fail', 'data': 'Network Error'})
};

// Make the request
req.send();
}

จากตัวอย่างเป็นการทำงานของ function เพื่อ get ค่าจาก url จะเห็นว่ามีการเรียกใช้งาน call back เพื่อส่งค่ากลับออกมา 3 ที่ และเมื่อต้องการใช้งาน จะมี code หน้าตา
ประมานนี้

get('test.json', function(result){
if(result.status == 'success')
//do somthing
else
//error
})

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

function get(url) {
// ส่งค่า promise ออกไป
return new Promise(function(resolve, reject) {
// Do the usual XHR stuff
var req = new XMLHttpRequest();
req.open('GET', url);

req.onload = function() {
// This is called even on 404 etc
// so check the status
if (req.status == 200) {
// เมื่อทำงานสำเร็จให้ส่ง req.response ออกไปเป็น then
resolve(req.response);
}
else {
// Otherwise reject with the status text
// เมื่อทำงานไม่สำเร็จให้ส่ง Error(req.statusText) ออกไปเป็น fail
reject(Error(req.statusText));
}
};

// Handle network errors
req.onerror = function() {
//เมื่อทำงานไม่สำเร็จให้ส่ง Error("Network Error") ออกไปเป็น fail
reject(Error("Network Error"));
};

// Make the request
req.send();
});
}

การใช้งานจะเป็น

get('story.json').then(function(response) {
//do somthing
}, function(error) {
//error
})

เป็นไงบ้างครับ ดูดีขึ้นเยอะเลยใช่ไหมครับ

การทำงานคือ เริ่มจากสร้าง object Promise ขึ้นมาก่อน โดยที่ constructor จะรับค่าเป็น function ที่มี arguments เป็น function 2 ตัวคือ resolve และ reject ซึ่ง resolve จะเอาไว้สั่งงานเมื่อการทำงานที่ต้องการสำเร็จ ส่วน reject เมื่อการทำงานไม่สำเร็จ เมื่อมีการ resolve (state fulfilled)ก็จะมาเข้า function then ในตัวข้างนอกที่ arguments ที่ 1 แต่ถ้า reject (state rejected) ก็จะมาทำคำสั่งใน arguments ที่ 2 แทน

Chaining

นอกจากนี้แล้วในบางครั้งเราต้องการที่จะนำผลลัทธ์ที่ได้ไปใช้ใน function อื่น ซึ่งปกติเราจะเขียนได้ดังนี้

get('story.json').then(function(response) {
return JSON.parse(response);
}).then(function(response) {
console.log("Yey JSON!", response);
})

เมื่อใช้ Promise เราสามารถเขียนได้สั้น ๆ ดังนี้

get('story.json').then(JSON.parse).then(function(response) {
console.log("Yey JSON!", response);
})

ดูง่ายขึ้นเลยใช่ไหมครับ ทีนี้เราก็ไม่ต้องเขียน call back ซ้อน ๆ กันไปเรื่อย ๆ แล้วครับ (แต่มาเขียน then ต่อ ๆ กันแทน ^-^)

สรุป

จากตัวอย่างที่แสดงให้ดูทั้งหมดนั้นเป็นแค่การใช้งานส่วนหนึ่งของ Promise เท่านั้นนะครับ แต่ก็เป็นส่วนหลัก ๆ ที่เราจะได้ใช้กัน ผมพยายามเลือกเฉพาะที่จะได้ใช้จริงมามากที่สุดเพราะเดียวบทความนี้จะยาวเกินไป ถ้าต้องการรายละเอียดเพิ่มเติมสามารถเข้าไปดูได้ที่ link นี้เลยครับ Promise หวังว่าต่อไปนี้เราจะได้เห็นการใช้ Promise แทนการใช้ call back กันบ้างนะครับ(เพื่อความสบายตาของคนที่มาอ่าน code) และขอให้ทุกคนสนุกกับการใช้งาน object Promise ใน Javascript กันทุกคนนะครับ

แหล้งอ้างอิง

http://www.somkiat.cc/asynchronous-javascript-with-callback-and-promise/

--

--