รูปจาก https://ima8.me/2015/01/12/node-js-say-hi-what-is-it/
เป็นการทำงานที่เกิดการ
รอ
เกิดขึ้น ไม่ว่าจะมีการทำงานพร้อมกันหลายๆงาน ยังไงงานก็ถูกกองไปอยู่ที่เดียว รองานเก่า จะทำเสร็จและตอบกลับมา
ข้อดีของ Blocking I/O
ข้อเสีย Blocking I/O
รูปจาก https://webapplog.com/you-dont-know-node/threading_java/
เป็นการทำงานอะไร สักอย่างโดนที่ไม่ต้องรอ การทำงานของงานก่อนหน้าทำเสร็จ ต่อให้มีการทำงานหลายๆงานพร้อมกัน ก็จะมีการแบ่งงานของ Thread เกิดขึ้น ไม่ได้ไปกองอยู่ที่ๆเดียวกัน
ข้อดีของ Non-Blocking I/O
ข้อเสีย Non-Blocking I/O
เป็นการโมเดลการ ทำงานแบบ Asynchronous
จะมีขั้นตอนประมาณนี้
อะไรสักอย่างที่เราสั่ง
ไปทำงานงาน
เดิมเสร็จก่อนจะไปเรื่องการทำงาน Async/Await จะมีการทำให้ Function ทำงาน แบบ Asynchronous อยู่อีก 2 แบบ คือ
เป็นการ เขียน Function ซ้อน Function เพื่อรอการทำงาน จะเป็นประมาณนี้
function A(param ,function(err,resA){
function B(resA,function(err,resB)){
// ทำไรสักอย่าง
})
)}
โดยปกติ จะให้เป็น parameter ตัวแรก เป็น error แล้วเช็คว่า ถ้า error เป็น null แสดงว่าไม่ error
เกิดขึ้นจาก การทำ callback function ที่มีความซับซ้อนมากๆ ( callback hell )
ประกอบไปด้วย 3 สถานะ
จะเป็นประมาณนี้
const datas = new Promise((resolved,reject)=> {// ทำอะไรสักอย่าง} )
.then(data=> // {resolved})
.catch(err=> // {rejected})
ด้วยความที่ Node มีการทำงานแบบ Non-Blocking I/O หรือ Asynchronous แต่การใช้งาน Function บางอย่างอาจจะเป็น Synchronous เช่น การทำอะไรกับฐานข้อมูล หรือทำอะไรที่ต้องรอให้คำสั่งนั้นทำงานเสร็จถึงจะไปทำอันถัดไป
จึงได้มีการนำ การ Async/Await มาทำในส่วนนี้
let datas = axios.get('xxx.com')
console.log(datas)
สิ่งที่ axios ส่งออกมาคือค่า Promise Object
เพราะ ภายใน axios เป็นการทำงาน แบบ Asynchronous ซึ่งสามารถรอรับค่าจากที่ axios ส่งมาได้อีกทางด้วยการ ใน callback
axios.get('xxx.com').then(data=>console.log(data))
แล้วถ้าในกรณี ที่มีการ เลือกให้ Axios หลายที่ ก็จะต้องทำประมาณนี้
//งาน A
axios.get('xxx.com').then(xdata=>console.log(xdata))
//งาน B
axios.get('yyy.com').then(ydata=>console.log(ydata))
ที่นี้ แล้วถ้าเป็นในกรณี ที่เราต้องการที่จะให้ งาน A ทำงานเสร็จก่อนแล้วจึงไปทำงาน B ละ
ก็จะได้ประมาณนี้
// งาน A
axios.get('xxx.com').then(xdata=>{
// งาน B
axios.get('yyy.com').then(ydata=>{
console.log(ydata)
})
})
ที่นี้ การทำงานของเราก็จะเป็นทำงานแบบเรียงตามลำดับได้แล้ว แต่แลกมากับปัญหา
callback hell
ลองนึกสภาพที่ มีการทำคำสั่งแบบนี้ สัก 10 ขั้นละ นอกจากมั่วแล้ว ยังอ่านยาก อีก จึงนำมาซึ่ง Async/Await
เกิดจากการข้อเสีย ที่ Promise พอลำดับเริ่มเยอะขึ้น มีการใช้ .then() ไปหลายชั้น คล้าย callback hell แต่ในที่นี้เรียกว่า promise hell
เช่น
// แบบปกติ
function A(){
console.log("A")
}
// แบบ async function
async function A(){
console.log("A")
}
ที่นี้ เรียกใช้ function ด้วย Await
async function main (){
let datas = await A();
console.log(data) // A
}
ยกตัวอย่างจาก axios ด้านบน
// แบบปกติ
axios.get('xxx.com').then(xdata=>{
// งาน B
axios.get('yyy.com').then(ydata=>{
console.log(ydata)
})
})
/// แบบ async function
async function call(){
let callA = await axios.get('xxx.com')
let callB = await axios.get('yyy.com')
}
เพียงเท่านี้ ก็จะสามารถ ทำงานเป็นลำดับ และอ่านง่ายขึ้นด้วย