TPA & Alibaba Cloud ผนึกกำลัง สร้างสรรค์สัมมนาและอบรม ต่อยอดความร่วมมือสู่อนาคต
เมื่อวันที่ 21 พฤศจิกายน ที่ผ่านมา คุณเซฟ พงษ์ศิริ นายก […]
นั้นเป็นการรอจังหวะให้การร้องขอและการตอบกลับเสร็จเป็นเรื่องๆไปจึงจะทำงานตามขั้นตอนการร้องขอครั้งใหม่
การร้องขอครั้งที่ 2 จะเกิดขึ้นได้ก็ต่อเมื่อ การร้องขอครั้งแรกได้รับการตอบกลับแล้ว ซึ่งหากผู้ตอบสนองทำงานได้ช้า ก็จะเกิดปัญหาคอขวด (Bottleneck)เกิดขึ้น
ซึ่งในเหตุการณ์ชีวิตจริง ก็เปรียบได้กับการไปสั่งกาแฟในร้านที่ไม่มีบัตรคิว และไม่จดเมนูให้ หากผู้ร้องขออยากได้กาแฟก็ต้องรอจนถึงรอบตัวเองเท่านั้นถึงจะได้สั่งและรอต่อไป
คำสั่งที่ 2 getProductList
function getUserInfo(){ for(var i=0;i<10;i++){ console.log('User Info no ' + i); } } function getProductList(){ for(var i=0;i<10;i++){ console.log('Product no ' + i); } } getUserInfo(); getProductList();
การส่งแบบ Asynchronous ก็จะตรงกันข้ามกับ Synchronous คือ สามารถส่งคำร้องขอไปได้เรื่อยๆ ไม่ต้องรอให้คำขอก่อนหน้าเสร็จก่อน ซึ่งในชีวิตจริง ก็เหมือนการเดินเข้าไปสั่งอาหารในร้าน Junk Food หรือ ร้านกาแฟ ที่มีการบริหารจัดการเรื่องคิว รับออเดอร์ลูกค้ามาก่อน ยังไม่จำเป็นต้องทำเสร็จ ก็รับออเดอร์ถ้ดไปได้เลย ก็จะทำให้ไม่เสียโอกาสในการให้บริการลูกค้าท่านอื่นๆ ซึ่งการเขียนโปรแกรมแบบ Asynchronous ในปัจจุบันก็มาพร้อมการบัญญัติศัพท์ใหม่ๆให้ดูเท่ห์ คือคำว่า None Blocking I/O
ในการเขียนโปรแกรมติดต่อฝั่งเซิร์ฟเวอร์ในงานจริง หากฟังก์ชั่น getUserInfo และ getProductList เป็นการร้องขอไปยังเครื่องเซิร์ฟเวอร์คนละเครื่อง หรือเซิร์ฟเวอร์เครื่องเดียวกัน แต่ผู้ใช้งานอยู่คนละประเทศ ฟังก์ชั่น getProductList ก็อาจทำงานเสร็จก่อน getUserInfo ได้ ซึ่งผู้พัฒนาต้องเข้าใจลำดับการทำงานของโปรแกรมแบบ Asynchronous เพื่อนำผลลัพธ์ที่ได้ไปใช้อย่างถูกต้อง
function getUserInfo(callback){
setTimeout(function(){
callback('got user info!');
},500);
}
function getProductList(callback){
setTimeout(function(){
callback('got product list!');
},100);
}
getUserInfo(function(result){
console.log(result);
});
getProductList(function(result){
console.log(result);
});
จากตัวอย่าง เรียงลำดับการเรียงฟังก์ชั่น getUserInfo ตามด้วย getProductList แต่เอ่ะทำไม getProductList เสร็จก่อนละ ในตัวอย่างนั้นเงื่อนไขชัดเจนคือกำหนดเวลา Timeout ไว้ แต่ในชีวิตจริงการเขียนโปรแกรมแบบ Asynchronous ติดต่อ Server และฐานข้อมูล เป็นเรื่องที่คาดเดาได้ยากว่าอันไหนจะเสร็จก่อน หากวางโค้ดตามลำดับแบบนี้ ถ้าในโปรแกรมต้องให้ UserInfo เสร็จก่อนถึงทำ getProductList รับรองว่าลำดับการทำงานของโปรแกรมผิดแน่ๆ
function name(option,callback){
callback(result);
}
การเรียกใช้
แล้ว callback มันไม่ดียังงัยละ
สรรพสิ่งบนโลกนี้ล้วนอนิจจัง ไม่มีอะไรสมบูรณ์แบบ เมื่อเราแก้ปัญหาอีกอย่าง เราก็จะเจอปัญหาอีกอย่าง สำหรับ callback สิ่งที่นักพัฒนาเจอปัญหาเท่าที่ทราบน่าจะมี ดังนี้
ตัวอย่าง
login(function(userInfo){
getMenu(userInfo,function(menuList){
genMenu(menuList,function(status){
showDefaultPage(status,function(){
});
log(userInfo,status);
})
ขั้นตอนการทำงาน
* จะเห็นได้จากโค้ดและ Bullets แสดงลำดับขั้นตอนการทำงาน ยิ่งโปรแกรมมีความซับซ้อนเท่าใด การเขียนโค้ดแบบ callback ก็ยิ่งเพิ่มความซับซ้อนให้เรามากขึ้นเท่านั้น
ตัวอย่าง callback hell
function a(n,cb){ cb(n); } a(1,function(n1){ a(2,function(n2){ a(3,function(n3){ a(4,function(n4){ a(5,function(n5){ a(6,function(n6){ a(7,function(n7){ n1+=n2+n3+n4+n5+n6+n7; console.log(n1); }) }) }); }); }); }) });
3. รัน node ch7_callback.js
node ch7_callback.js 28
จากตัวอย่างจะเห็นได้ว่าถ้ามีการเขียนโค้ดแบบ asynchronous แล้วต้องรอผลลัพธ์จากอีกฟังก์ชั่นหนึ่ง แล้วมีลำดับต้องทำงานต่อไปเรื่อยๆ โค้ดจะดูน่าเกลียดมาก ซึ่งในตัวอย่างนี้ยังไม่มีการเขียนติดต่อกับไฟล์หรือฐานข้อมูลทำให้อาจจะยังให้มือใหม่ยังไม่เข้าใจเกี่ยวกับ callback และ Asynchronous ได้ 100 % ไว้ในตอนต่อๆไปจะมีการเขียน callback และนำ ไลบรารี่ต่างๆที่เข้ามาช่วยให้บริการจัดการโค้ดได้ดีขึ้น ฝึกบ่อยๆแล้วจะเข้าใจขึ้นเรื่อยๆ
ติดตามกับตอนที่ 8 การเขียน Asynchronous ด้วย Promise