?>

[:th]NodeJS ตอนที่ 7 [การเขียนโปรแกรมแบบ Callback][:]

0

[:th]

Java Script Callback ก็คือ การเรียกฟังก์ชั่นแบบ Asynchronous
เอ่ะ แล้วการเรียกแบบ Asynchronous มันคืออะไรอีกเนี่ย ?
คำว่า Asynchronous กับ Synchronous ในแวดวงวิศวกรรมหรือเทคโนโลยีมักจะได้ยินกันบ่อยๆ ซึ่งมักใช้เกี่ยวกับการรับส่ง ข้อมูล สัญญาณ ในรูปแบบต่างๆ ซึ่งการส่งข้อมูลหรือสัญญาณต่างๆนั้นก็
ต้องมี ผู้ร้องขอ – ผู้ตอบกลับ
การส่งแบบ Synchronous 

นั้นเป็นการรอจังหวะให้การร้องขอและการตอบกลับเสร็จเป็นเรื่องๆไปจึงจะทำงานตามขั้นตอนการร้องขอครั้งใหม่

การร้องขอครั้งที่ 2 จะเกิดขึ้นได้ก็ต่อเมื่อ การร้องขอครั้งแรกได้รับการตอบกลับแล้ว ซึ่งหากผู้ตอบสนองทำงานได้ช้า ก็จะเกิดปัญหาคอขวด (Bottleneck)เกิดขึ้น

ซึ่งในเหตุการณ์ชีวิตจริง ก็เปรียบได้กับการไปสั่งกาแฟในร้านที่ไม่มีบัตรคิว และไม่จดเมนูให้ หากผู้ร้องขออยากได้กาแฟก็ต้องรอจนถึงรอบตัวเองเท่านั้นถึงจะได้สั่งและรอต่อไป

เปรียบเทียบกับการเขียนโปรแกรม
คำสั่งที่ 1 getUserInfo

คำสั่งที่ 2 getProductList

* คำสั่ง getProductList จะไม่เกิดขึ้นเลยถ้า getUserInfo ยังไม่เสร็จ
ตัวอย่าง JavaScript http://jsfiddle.net/apaichon/z59csxLk/

 

การส่งแบบ Asynchronous

การส่งแบบ Asynchronous ก็จะตรงกันข้ามกับ Synchronous คือ สามารถส่งคำร้องขอไปได้เรื่อยๆ ไม่ต้องรอให้คำขอก่อนหน้าเสร็จก่อน ซึ่งในชีวิตจริง ก็เหมือนการเดินเข้าไปสั่งอาหารในร้าน Junk Food หรือ ร้านกาแฟ ที่มีการบริหารจัดการเรื่องคิว รับออเดอร์ลูกค้ามาก่อน ยังไม่จำเป็นต้องทำเสร็จ ก็รับออเดอร์ถ้ดไปได้เลย ก็จะทำให้ไม่เสียโอกาสในการให้บริการลูกค้าท่านอื่นๆ ซึ่งการเขียนโปรแกรมแบบ Asynchronous ในปัจจุบันก็มาพร้อมการบัญญัติศัพท์ใหม่ๆให้ดูเท่ห์ คือคำว่า None Blocking I/O

ในการเขียนโปรแกรมติดต่อฝั่งเซิร์ฟเวอร์ในงานจริง หากฟังก์ชั่น getUserInfo และ getProductList เป็นการร้องขอไปยังเครื่องเซิร์ฟเวอร์คนละเครื่อง หรือเซิร์ฟเวอร์เครื่องเดียวกัน แต่ผู้ใช้งานอยู่คนละประเทศ ฟังก์ชั่น getProductList ก็อาจทำงานเสร็จก่อน getUserInfo ได้ ซึ่งผู้พัฒนาต้องเข้าใจลำดับการทำงานของโปรแกรมแบบ Asynchronous เพื่อนำผลลัพธ์ที่ได้ไปใช้อย่างถูกต้อง

ตัวอย่าง JavaScript http://jsfiddle.net/apaichon/27aqLfnc/

จากตัวอย่าง เรียงลำดับการเรียงฟังก์ชั่น getUserInfo ตามด้วย getProductList แต่เอ่ะทำไม getProductList เสร็จก่อนละ ในตัวอย่างนั้นเงื่อนไขชัดเจนคือกำหนดเวลา Timeout ไว้ แต่ในชีวิตจริงการเขียนโปรแกรมแบบ Asynchronous ติดต่อ Server และฐานข้อมูล เป็นเรื่องที่คาดเดาได้ยากว่าอันไหนจะเสร็จก่อน หากวางโค้ดตามลำดับแบบนี้ ถ้าในโปรแกรมต้องให้ UserInfo เสร็จก่อนถึงทำ getProductList รับรองว่าลำดับการทำงานของโปรแกรมผิดแน่ๆ

รูปแบบการประกาศฟังก์ชั่นแบบ Callback
  • callback – ใช้คืนค่าผลลัพธ์จากการ callback  สามารถเขียนเป็นอะไรก็ได้ตามที่ระบุไว้ในตอนรับค่ามาเช่น  function a(opt,f){f(result);}
  • callback() – ส่งค่าผลลัพธ์กลับไปยังฟังก์ชั่นที่เรียก
  • result – ผลลัพ์ธ์ที่ส่งกลับไป สามารถส่งเป็นรูปแบบ json ฟังก์ชั่น variable ต่างๆที่ javascript รองรับ

การเรียกใช้ 

  • name(function(result){
    });
  •  result – ผลลัพธ์ที่ได้รับจากการ callback จะตั้งชื่ออะไรก็ได้ที่ตรงหลักการของ JavaScript ไม่ตรงกับคำสงวน ไม่ตรงกับชื่อตัวแปรที่เป็น global variable

แล้ว callback มันไม่ดียังงัยละ 
สรรพสิ่งบนโลกนี้ล้วนอนิจจัง ไม่มีอะไรสมบูรณ์แบบ เมื่อเราแก้ปัญหาอีกอย่าง เราก็จะเจอปัญหาอีกอย่าง สำหรับ callback สิ่งที่นักพัฒนาเจอปัญหาเท่าที่ทราบน่าจะมี ดังนี้

  • หากลืมเขียน callback() เพื่อส่งผลลัพธ์กลับ ก็จะไม่ทราบว่าโปรแกรมทำงานถึงไหน เงียบหายไปเลย อันนี้ส่วนใหญ่เป็นข้อผิดพลาดของนักพัฒนาเอง
  • หากต้องการผลลัพธ์ตามลำดับขั้น การเขียนฟังก์ชั่นที่ซับซ้อน callback ช่วยให้คุณปวดหัวได้มากขึ้นแน่นอน ที่เราเรียกว่า Callback Hell

 ตัวอย่าง

ขั้นตอนการทำงาน

  • เมื่อ login เสร็จได้ข้อมูล userInfo
    • ทำการดึงข้อมูล menu ที่ผู้ใช้งานมีสิทธิเข้าถึงได้
      • genMenu ทำการสร้างเมนูบนหน้าจอ
        • ทำการแสดงผลหน้าที่กำหนดเริ่มต้น
        • ทำการ log ข้อมูลการเข้าระบบของผู้ใช้

* จะเห็นได้จากโค้ดและ Bullets แสดงลำดับขั้นตอนการทำงาน ยิ่งโปรแกรมมีความซับซ้อนเท่าใด การเขียนโค้ดแบบ callback ก็ยิ่งเพิ่มความซับซ้อนให้เรามากขึ้นเท่านั้น

ตัวอย่าง callback hell

  1. สร้างไฟล์ชื่อ ch7_callback.js
  2. ป้อนโค้ด ดังนี้

3. รัน node ch7_callback.js

จากตัวอย่างจะเห็นได้ว่าถ้ามีการเขียนโค้ดแบบ asynchronous แล้วต้องรอผลลัพธ์จากอีกฟังก์ชั่นหนึ่ง แล้วมีลำดับต้องทำงานต่อไปเรื่อยๆ โค้ดจะดูน่าเกลียดมาก ซึ่งในตัวอย่างนี้ยังไม่มีการเขียนติดต่อกับไฟล์หรือฐานข้อมูลทำให้อาจจะยังให้มือใหม่ยังไม่เข้าใจเกี่ยวกับ callback และ Asynchronous ได้ 100 % ไว้ในตอนต่อๆไปจะมีการเขียน callback และนำ ไลบรารี่ต่างๆที่เข้ามาช่วยให้บริการจัดการโค้ดได้ดีขึ้น ฝึกบ่อยๆแล้วจะเข้าใจขึ้นเรื่อยๆ

ติดตามกับตอนที่ 8 การเขียน Asynchronous ด้วย Promise

 [:]

Share.

About Author

Leave A Reply

80 + = 81