ช่วงนี้จับงาน Web เยอะ และใช้งาน jQuery ในการจัดการหน้า Webpage เป็นหลัก ใน jQuery เอง ได้มีการใช้งาน Callback ค่อนข้างเยอะ เช่นการดัก Event ต่าง ๆ วันนี้คันไม้คันมือ หลังจากไม่ได้เขียนมาเป็นเดือน เลยมาเขียนเกี่ยวกับ Callback ให้อ่านกัน
Callback แปลกันตรง ๆ ตัว ว่าโทรกลับ ในทาง Programming ก็เช่นกัน Callback มีไว้สำหรับ เรียกใช้งานกลับ… อย่าเพิ่งทำหน้าแบบนี้กันนะครับ
สมมติว่า เวลาเราเขียนโปรแกรม แล้วต้องการให้ Function นึง ทำงานเสร็จก่อน หลังจากนั้นค่อยทำงานอีก Function นึง ขอยกตัวอย่าง Code เป็นภาษา JavaScript ดังนี้
1 2 3 4 5 6 7 8 9 10 |
function fnWorkSecond() { document.writeln("Work Second<br>"); } function fnWorkFirst() { document.writeln("Work First<br>"); } fnWorkFirst(); fnWorkSecond(); |
1 2 |
Work First Work Second |
จาก Code บรรทัดที่ 9 เรียกใช้งาน Function fnWorkFirst() และบรรทัดที่ 10 เรียกใช้งาน Function fnWorkSecond();
ดูเหมือนจะไม่มีอะไร แต่หากว่า fnWorkFirst นั้น ทำงานเป็นแบบ Asynchronous นั่นหมายความว่า ขณะที่ fnWorkFirst ทำงานอยู่นั้น โปรแกรมก็จะไม่หยุดรอทำงาน ลองดูตัวอย่างต่อไปกัน
1 2 3 4 5 6 7 8 9 10 |
function fnWorkSecond() { document.writeln("Work Second<br>"); } function fnWorkFirst() { document.writeln("Work First<br>"); } setTimeout(fnWorkFirst, 1000); fnWorkSecond(); |
1 2 |
Work Second Work First |
บรรทัดที่ 9 ได้เปลี่ยนเป็นการใช้งาน function setTimeout เพื่อกำหนดให้รอเวลา 1000 ms ก่อน แล้วค่อยเรียกใช้งาน fnWorkFirst เผื่อจำลองการทำงานคล้าย ๆ แบบ Asynchronous สังเกตุผลลัพธ์ จะเห็นว่า ไม่มีการรอให้ fnWorkFirst ทำงานเสร็จก่อน ค่อยเรียก fnWorkSecond ทำงาน ทำให้ได้ผลลัพธ์จาก fnWorkSecond ก่อนนั่นเอง
หากว่าเราต้องการ Output เหมือนเดิม จึงจำเป็นต้องให้ fnWorkFirst เรียกใช้งาน fnWorkSecond แทน ดังนี้
1 2 3 4 5 6 7 8 9 10 |
function fnWorkSecond() { document.writeln("Work Second<br>"); } function fnWorkFirst() { document.writeln("Work First<br>"); fnWorkSecond(); } fnWorkFirst(); |
ซึ่งจะได้ผลลัพธ์เดียวกันกับตัวอย่างแรก
ทีนี้ ถ้าหากว่า fnWorkFirst ไม่ใช่เป็น Function ที่เราเป็นผู้พัฒนาขึ้นมาเองล่ะ แล้วจะทำยังไงให้ fnWorkFirst นั้น เรียกใช้งาน fnWorkSecond ให้เราได้ หลังจากที่ fnWorkFirst ทำงานเสร็จแล้ว
คำตอบก็คือ Callback นั่นเอง มาดู Code กันเลยดีกว่า
1 2 3 4 5 6 7 8 9 10 |
function fnWorkSecond() { document.writeln("Work Second<br>"); } function fnWorkFirst(callback) { document.writeln("Work First<br>"); callback(); } fnWorkFirst(fnWorkSecond); |
ที่บรรทัดที่ 10 มีการเรียกใช้งาน fnWorkFirst โดยมีการส่ง Parameter 1 ตัว คือ “ชื่อ” Function fnWorkSecond เข้าไป!?
ส่งชื่อ Function เข้าไปทำไม!? ลองดู Function fnWorkFirst ที่บรรทัดที่ 5 ดูซิครับ มีการรับ Parameter 1 ตัว และเรียกใช้งานที่บรรทัดที่ 7 นี่แหล่ะ ที่เราเรียกกันว่า Callback (เห็นไม๊ มันโทรกลับมาแล้ว!!!)
ซึ่งผลลัพธ์ก็เหมือนกันกับตัวอย่างแรก
และนอกจากให้ fnWorkFirst ทำการ Callback ให้แล้ว สามารถส่งข้อมูลผ่านทาง Parameter ให้ได้ด้วยนะ ลองดูตัวอย่างกันเลย
1 2 3 4 5 6 7 8 9 10 11 |
function fnWorkSecond(data_back) { document.writeln("Work Second<br>"); document.writeln(data_back); } function fnWorkFirst(callback) { document.writeln("Work First<br>"); callback("send data back"); } fnWorkFirst(fnWorkSecond); |
1 2 3 |
Work First Work Second send data back |
สังเกตุบรรทัดที่ 8 ใน fnWorkFirst มีการเรียกใช้งาน Callback พร้อมกลับส่ง Parameter ให้ 1 ตัว เพราะฉะนั้น Function ที่ส่งเข้ามาให้กับ fnWorkFirst จะรับ Parameter ได้ 1 ตัว ดังในบรรทัดที่ 1 ซึ่งใน JavaScript เปิดโอกาสให้สามารถกำหนด Parameter ไม่ตรงกันได้ เพราะฉะนั้น ใน Function fnWorkSecond หากไม่มี Parameter สำหรับรับค่าจากการ Callback ก็จะไม่เกิด Error ใด ๆ เพียงแต่จะไม่ได้รับค่าที่ fnWorkFirst ส่งกลับมาให้เท่านั้นเอง
สุดท้าย การเขียน Code ในลักษณะ Callback นั้น สามารถเขียนในอีกรูปแบบนึงได้ ดังนี้
1 2 3 4 5 6 7 8 9 |
function fnWorkFirst(callback) { document.writeln("Work First<br>"); callback("send data back"); } fnWorkFirst(function (data_back) { document.writeln("Work Second<br>"); document.writeln(data_back); }); |
Function fnWorkFirst ไม่มีแก้ไขใด ๆ แต่ Function fnWorkSecond นั้นหายไปแล้ว ลองสังเกตุบรรทัดที่ 6-9 ตั้งแต่คำว่า function (data_back) { จนถึง } นั่นก็คือ fnWorkSecond นั่นเอง เพียงแต่ไม่ต้องตั้งชื่อ Function!! (ชอบใช่ไม๊ล่ะ ไม่ต้องคิดชื่อ Function เชื่อว่า Programmer หลายท่าน บางครั้ง การตั้งชื่อตัวแปร/ฟังก์ชั่น นั้น เป็นเรื่องยากกว่าการเขียน Code ยิ่งนัก
) แต่ผลการทำงานนั้น เหมือนในตัวอย่างก่อนหน้านี้เป๊ํะ
หวังว่าคงเข้าใจคำว่า Callback กันมากขึ้นนะครับ Callback นั้น ไว้สำหรับส่ง Function ให้ภายใน Function เรียกใช้งานนั่นเอง Function ที่ถูกส่งเข้าไป จึงเรียกกันว่า Callback Function นั่นเอง
ลองดูตัวอย่าง Callback ในภาษาต่าง ๆ ที่ Wikipedia กันดูนะครับ
คราวหน้าจะเอาตัวอย่างในภาษา VB.NET มาให้ดูกันบ้าง คอยติดตามนะครับ ว่าใน VB.NET มันจะใช้งาน Callback ยังไง