ก่อนจะใช้ Await / Async มันมีปัญหาอะไร ?
สำหรับคนที่เขียน JavaScript อาจจะรู้หรือยังไม่รู้ก็ได้ว่า JavaScript นั้นมีคำสั่งที่ทำงานแบบ asynchronous ก็คือเวลาที่เราสั่งงานอะไรไปแล้วถ้าเป็นงานที่ใช้เวลานาน มันก็จะไล่ไปทำคำสั่งถัดไปเลยโดยไม่ได้รอให้คำสั่งก่อนหน้าทำเสร็จ มาดูตัวอย่างง่ายๆต่อไปนี้กัน
function taskOne() { setTimeout(function () { console.log("this is task 1"); }, 500); } function taskTwo() { console.log("this is task 2"); } function taskThree() { setTimeout(function() { console.log("this is task 3"); }, 1000) } taskOne(); taskTwo(); taskThree();
Output:
this is task 2 this is task 1 this is task 3
จากโค้ดตัวอย่างจะเห็นว่ามีฟังก์ชันอยู่ 3 ฟังก์ชัน คือ taskOne, taskTwo และ taskThree ที่แต่ละฟังก์ชันจำลองการใช้เวลาทำงานจนเสร็จต่างกันด้วย setTimeout ทีนี้พอเราเรียกใช้ให้ทำงานเรียงลำดับ taskOne > taskTwo > taskThree แต่พอดูผลลัพธ์แล้วกลับได้เป็น 2 > 1 > 3 ซะงั้น นั่นก็เพราะ setTimeout() เป็นคำสั่งที่ทำงานแบบ asynchronous ทำให้ JavaScript จะไล่ทำงานไปตามคำสั่งไปเรื่อยๆ โดยไม่ได้สนใจว่าคำสั่งที่เพิ่งเรียกไปก่อนหน้านั้นจะเสร็จหรือไม่ การทำงานแบบนี้จึงอาจเกิดปัญหากับงานที่ต้องการให้ทำตามลำดับได้ ซึ่ง JavaScript ก็มีวิธีการจัดการด้วยการใช้ Promise (อ่านเพิ่มเติมได้ที่ ………) ให้ใช้กันได้
เย่ๆ รับมือกับการทำงานแบบ asynchronous ของ JavaScript ได้แล้ว จบแยกย้าย…
แต่เดี๋ยวก่อน !!! ถ้ามันจบง่ายแบบนั้นก็คงไม่มีบทความนี้เกิดขึ้นมา ลองดูโค้ดต่อไปนี้กันก่อน
taskOne().then(function(){ taskTwo().then(function(){ taskThree(); }) });
Output:
this is task 1 this is task 2 this is task 3
โค้ดด้านบนนี้ที่ใช้ Promise จะเห็นว่ามันก็ทำงานเรียงลำดับถูกต้องแล้วนี่นา แต่โค้ดของเรามันก็เริ่มจะดูอ่านยากขึ้นตามไปด้วย อาจจะยังไม่เห็นภาพชัดพอ งั้นถ้าหากว่าเรามีงานที่ต้องทำถึง 10 งาน ซึ่งทุกงานเป็น asynchronous แล้วใช้เวลาไม่เท่ากันล่ะ
taskOne().then(function () { taskTwo().then(function () { taskThree().then(function () { taskFour().then(function () { taskFive().then(function () { taskSix().then(function () { taskSeven().then(function () { taskEight().then(function () { taskNine().then(function () { taskTen(); }) }) }) }) }) }) }) }) });
อืมมม… น่าจะเข้าใจแล้วใช่มั้ยว่าทำไมแค่ Promise อย่างเดียวถึงยังไม่พอ จนต้องเกิดเป็น Await / Async ขึ้นมา
แล้ว Await / Async นี่มันใช้งานยังไง
await ใช้เพื่อบอกให้ JavaScript รอจนกว่าคำสั่งนั้นจะเสร็จ ถึงค่อยไปทำงานอันต่อไป โดยฟังก์ชันที่จะมี await อยู่ข้างในได้ต้องประกาศเป็น async เสมอ
ลองดูโค้ดด้านล่างนี้แก้งงกันก่อน
async function main() { await taskOne(); } main();
ทีนี้พอเราเอาการใช้ await และ async ไปใช้กับงานทั้ง 10 ของเรา โค้ดก็จะออกมาแบบนี้
async function main() { await taskOne(); await taskTwo(); await taskThree(); await taskFour(); await taskFive(); await taskSix(); await taskSeven(); await taskEight(); await taskNine(); await taskTen(); } main();
Output:
this is task 1 this is task 2 this is task 3 this is task 4 this is task 5 this is task 6 this is task 7 this is task 8 this is task 9 this is task 10
จบแล้วครับสำหรับการใช้ await และ async … คราวนี้จบแล้วจริงๆนะ เท่านี้โค้ดของเราก็สวยงามอ่านง่ายแล้วอีซี่สุดๆ
วิธีการใช้ Await และ Async ง่ายๆแบบนี้ก็ลองนำไปปรับใช้กับโค้ดที่เขียนกันได้นะครับ หรือจะใช้เพียงแค่ Promise ก็ลองพิจารณาดูว่างานที่เราเหมาะสมกับอะไร จะได้ไม่เป็นการเพิ่มงาน เพิ่มภาระให้กับตัวเองนะครับ