Contents

ข้อมูลเบื้องต้นเกี่ยวกับการเขียนโปรแกรมที่ขับเคลื่อนด้วยเหตุการณ์ใน Node.js

ประเด็นที่สำคัญ

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

การเขียนโปรแกรมที่ขับเคลื่อนด้วยเหตุการณ์ได้กลายเป็นวิธีการที่แพร่หลายในเว็บแอปพลิเคชัน โดยที่ตัวฟังเหตุการณ์จะถูกเปิดใช้งานเมื่อผู้ใช้โต้ตอบกับ Document Object Model (DOM)

การรวมการเขียนโปรแกรมตามเหตุการณ์ใน Node.js สามารถทำได้ได้อย่างราบรื่นผ่านการใช้คลาส EventEmitter ซึ่งอำนวยความสะดวกในการสร้างเหตุการณ์ที่ปรับแต่งและการแนบตัวจัดการเหตุการณ์เพื่อการจัดการที่เหมาะสม

เมื่อพัฒนาแอปพลิเคชันซอฟต์แวร์ การเลือกกระบวนทัศน์การเขียนโปรแกรมที่เหมาะสมถือเป็นการตัดสินใจที่สำคัญที่ต้องทำ ในที่สุดกระบวนทัศน์มีอิทธิพลต่อโครงสร้างและการจัดระเบียบของโค้ดตลอดจนประสิทธิภาพและการบำรุงรักษา ดังนั้นจึงเป็นเรื่องสำคัญที่จะต้องพิจารณาอย่างรอบคอบว่ากระบวนทัศน์ใดที่สอดคล้องกับข้อกำหนดและเป้าหมายเฉพาะของโครงการมากที่สุด ก่อนที่จะตัดสินใจใช้แนวทางเฉพาะ

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

กิจกรรมคืออะไร?

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

ในขอบเขตของการเขียนโปรแกรมคอมพิวเตอร์ เหตุการณ์พื้นฐานจะแสดงตัวอย่างโดยกระบวนการกดปุ่มบนแป้นพิมพ์เพื่อดำเนินการงานเฉพาะ เมื่อการดำเนินการนี้เกิดขึ้น จะทำให้เกิดเหตุการณ์ที่เรียกว่า"เหตุการณ์"ซึ่งต่อมาจะเปิดใช้งานรูทีนย่อยที่เรียกว่า"ผู้ฟัง"หรือ"ตัวจัดการ"

การเขียนโปรแกรมที่ขับเคลื่อนด้วยเหตุการณ์คืออะไร?

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

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

ในบริบทของการพัฒนาเว็บแอปพลิเคชัน การใช้ตัวฟังเหตุการณ์ได้กลายเป็นแนวทางที่นำมาใช้อย่างกว้างขวาง เนื่องจากถูกกระตุ้นเพื่อตอบสนองต่อการโต้ตอบของผู้ใช้กับ Document Object Model (DOM)

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

/th/images/event_driven_visualization.jpg

การเขียนโปรแกรมที่ขับเคลื่อนด้วยเหตุการณ์ใน Node.js

event loop ใน JavaScript ซึ่งเป็นรากฐานสำคัญของอักขระอะซิงโครนัสของรันไทม์ Node.js ใช้สถาปัตยกรรมที่ขับเคลื่อนด้วยเหตุการณ์โดยธรรมชาติ โดยใช้ประโยชน์จากโมดูล EventEmitter ที่รวมไว้เพื่อให้มั่นใจว่าการดำเนินงานมีความก้าวหน้าอย่างต่อเนื่องและมีประสิทธิภาพ

ด้วยการใช้แนวทางที่ขับเคลื่อนด้วยเหตุการณ์ Node.js ช่วยให้สามารถพัฒนาแอปพลิเคชันบนเซิร์ฟเวอร์ที่สามารถรองรับการโต้ตอบของผู้ใช้ การดำเนินการอินพุต/เอาท์พุต และการประมวลผลข้อมูลแบบเรียลไทม์ ทั้งหมดนี้ไม่มีกลไกการบล็อกที่ขัดขวาง จึงเพิ่มประสิทธิภาพโดยรวมและมอบความราบรื่น ประสบการณ์ผู้ใช้

การใช้การเขียนโปรแกรมที่ขับเคลื่อนด้วยเหตุการณ์ใน Node.js อาจเป็นกระบวนการที่ไม่ซับซ้อนเมื่อมีความเข้าใจที่ครอบคลุมเกี่ยวกับพื้นฐานที่เกี่ยวข้องกับการกำหนด การเปิดใช้งาน และการจัดการเหตุการณ์

คลาส EventEmitter

การใช้EventEmitterclassinNode.jsอนุญาตให้มีการสร้างเหตุการณ์แบบกำหนดเองและการแนบของผู้ฟังเหตุการณ์เพื่อจัดการพวกเขา เพื่อรวมรหัสคลาสintomy นำเข้าจากโมดูลเหตุการณ์ผ่านคุณลักษณะนี้:

 // CommonJS
const { EventEmitter } = require("events")

// ES6
import { EventEmitter } from "events" 

เมื่อสร้างอินสแตนซ์ของคลาส EventEmitter แล้ว คุณจะสามารถเข้าถึงได้ภายในแอปพลิเคชันของคุณเพื่อนำไปใช้ประโยชน์ ซึ่งช่วยให้สามารถเริ่มต้นกระบวนการปล่อยก๊าซเรือนกระจกและการจัดการเหตุการณ์ได้

ตัวอย่างเช่น:

 const FoodEvents = new EventEmitter()

การใช้วิธี’on’การเพิ่มผู้ฟังผ่านกลยุทธ์’addListener’และการเปิดใช้งานแนวทาง’ครั้งเดียว'

การใช้คุณสมบัติ on ถือเป็นการดำเนินการพื้นฐานสำหรับการรวมตัวจัดการเหตุการณ์ โดยที่เมธอด addEventListener() นำเสนอความสามารถที่เหมือนกันในการรับการแจ้งเตือนเหตุการณ์ กลไกทั้งสองต้องการข้อกำหนดเฉพาะของเหตุการณ์ที่กำหนดพร้อมกับฟังก์ชันตามความต้องการซึ่งทำหน้าที่เป็นส่วนประกอบที่เกิดปฏิกิริยา คุณสามารถใช้ทางเลือกเหล่านี้ได้อย่างราบรื่น

หากต้องการใช้วิธีการ “เปิด” เพื่อจัดการเหตุการณ์เฉพาะ ให้ทำตามขั้นตอนเหล่านี้:

 FoodEvents.on("cookie_ready", (data) => {
    console.log("Cookie ready for packaging, data received: ", data);
})

แทนที่จะใช้เหตุการณ์"on"ใน JavaScript เราสามารถใช้วิธี"addListener"แทนได้ทันที

 FoodEvents.addListener("cookie_ready", (data) => {
    console.log(
        "Cookie will now be packaged and sent out, data received: ",
        data
    );
})

ทั้งสองอินสแตนซ์ของการเพิ่มฟังก์ชันการเรียกกลับให้กับอาร์เรย์ของตัวฟังเหตุการณ์สำหรับเหตุการณ์"cookie\_ready"ช่วยให้มั่นใจได้ว่าฟังก์ชันเหล่านั้นจะถูกดำเนินการตามลำดับเมื่อถูกทริกเกอร์ การเรียกใช้อย่างใดอย่างหนึ่งส่งผลให้มีการดำเนินการฟังก์ชันโทรกลับตามลำดับ

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

เพื่ออำนวยความสะดวกให้เหตุการณ์เอกพจน์เกิดขึ้น ให้ใช้รูปแบบซิงเกิลตันร่วมกับคอนเทนเนอร์ Unity แนวทางนี้ช่วยให้มั่นใจได้ว่ามีเพียงอินสแตนซ์เดียวของคลาสที่ต้องการเท่านั้นที่ถูกสร้างและดูแลรักษาตลอดอายุการใช้งานของแอปพลิเคชันของคุณ โดยสามารถจัดการขอบเขตของเหตุการณ์ที่เป็นปัญหาได้อย่างมีประสิทธิภาพ

 FoodEvents.once("cookie_sent", (data) => {
    console.log("Cookie is sent out, data received: ", data);
})

ในสถานการณ์สมมตินี้ ผู้ส่งจะเข้าร่วมเหตุการณ์ cookie\_sent เพียงครั้งเดียวและกำจัดฟังก์ชันการเรียกกลับหลังจากนั้นจึงมีการดำเนินการ

เทคนิคที่กล่าวมาข้างต้นทั้งหมดให้ผลเอนทิตีต้นทาง ดังนั้นจึงเปิดใช้งานการเรียกใช้วิธีใดวิธีหนึ่งติดต่อกันระหว่างกัน

โปรดจำไว้ว่าเพื่อให้ใครสักคนประมวลผลเหตุการณ์ที่เกิดขึ้น แอปพลิเคชันที่เกี่ยวข้องจะต้องเผยแพร่เหตุการณ์ดังกล่าวโดยการปล่อยเหตุการณ์ดังกล่าวในช่วงหัวเลี้ยวหัวต่อ ต่อไปนี้เป็นตัวอย่างที่แสดงให้เห็นถึงการปล่อยเหตุการณ์ cookie\_ready โดยใช้เมธอด emit:

 function bakeCookie() {
    console.log("Cookie is baking, almost ready...")

    setTimeout(() => {
        FoodEvents.emit("cookie_ready", { flavor: "vanilla cookie" })
    }, 3000)
}

bakeCookie() 

เมื่อรันโค้ดที่กำหนด ซึ่งแสดงข้อความในคอนโซลที่ระบุว่ากำลังเตรียมคุกกี้ หยุดชั่วคราวเป็นเวลาสามวินาที และทริกเกอร์เหตุการณ์ cookie\_ready เราสามารถคาดหวังได้ว่าจะได้เห็นการแสดงภาพที่คล้ายกับกราฟิกที่ปรากฎ:

/th/images/console_output.jpg

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

คลาส EventEmitter มีวิธีการเพิ่มเติม ได้แก่:

ฟังก์ชัน removeListener ทำหน้าที่กำจัดการเกิดขึ้นของ Listener จากคอลเลกชั่นตัวจัดการเหตุการณ์ที่เกี่ยวข้องกับองค์ประกอบหรืออ็อบเจ็กต์เฉพาะ ในขณะที่วิธีการทางเลือก off ให้ฟังก์ชันการทำงานที่คล้ายกัน

เมธอด prependListener ใช้เพื่อลงทะเบียน Listener ด้วยตัวปล่อยเหตุการณ์ที่ระบุ และวางไว้ที่จุดเริ่มต้นของรายชื่อ Listener สำหรับเหตุการณ์นั้น ๆ ต่างจากเมธอด addListener ที่ต่อท้าย Listener ใหม่ต่อท้ายคิว Listener ที่มีอยู่ เมธอด prependListener ช่วยให้มั่นใจได้ว่า Listener ที่เพิ่มเข้ามาใหม่จะทำงานก่อน Listener อื่นๆ ที่ลงทะเบียนไว้ก่อนหน้านี้ทั้งหมด

ฟังก์ชัน prependOnceListener ทำงานคล้ายกับ prependListener โดยมีความแตกต่างที่สำคัญคือผู้ฟังที่ระบุจะถูกดำเนินการเพียงครั้งเดียว ซึ่งคล้ายคลึงกับพฤติกรรมที่แสดงโดยเมธอด ครั้งเดียว

ฟังก์ชัน removAllListeners ทำหน้าที่กำจัดสมาชิกทั้งหมดที่เกี่ยวข้องกับเหตุการณ์ที่กำหนดไว้โดยเฉพาะ หรือผู้ฟังทุกคนในกรณีที่ไม่มีการโต้แย้ง

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

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

ใน Node.js เป็นเรื่องปกติที่จะจำกัดจำนวนผู้ฟังที่สามารถลงทะเบียนสำหรับกิจกรรมได้ เพื่อหลีกเลี่ยงไม่ให้หน่วยความจำรั่วไหล ตามค่าเริ่มต้น แพลตฟอร์มจะส่งคำเตือนหากมีการเพิ่มผู้ฟังมากกว่าสิบคนในกิจกรรม อย่างไรก็ตาม ข้อจำกัดนี้สามารถแทนที่ได้โดยใช้เมธอด setMaxListeners นอกจากนี้ เราอาจใช้ฟังก์ชัน getMaxListeners เพื่อกำหนดจำนวนผู้ฟังสูงสุดในปัจจุบันที่อนุญาตสำหรับวัตถุเฉพาะ

แพ็คเกจเหตุการณ์นำเสนอชุดคุณลักษณะที่แข็งแกร่งซึ่งออกแบบมาเพื่ออำนวยความสะดวกในการเขียนโปรแกรมตามเหตุการณ์ภายในสภาพแวดล้อม Node.js

แนวทางปฏิบัติที่ดีที่สุดในการเขียนโปรแกรมที่ขับเคลื่อนด้วยเหตุการณ์มีอะไรบ้าง

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

ตรวจสอบให้แน่ใจว่าการตั้งชื่อเหตุการณ์นั้นกระชับและให้ข้อมูล เพื่อส่งเสริมสภาพแวดล้อมการเขียนโปรแกรมที่มีการจัดระเบียบอย่างดีและบำรุงรักษาได้ง่าย

การใช้เทคนิคการจัดการข้อผิดพลาดและการบันทึกที่มีประสิทธิภาพเป็นสิ่งสำคัญในการอำนวยความสะดวกในกระบวนการแก้ไขปัญหาที่อาจเกิดขึ้นระหว่างการพัฒนาแอปพลิเคชัน การใช้แนวทางปฏิบัติที่ดีที่สุดเหล่านี้ช่วยให้นักพัฒนาสามารถระบุและแก้ไขปัญหาใดๆ ที่เกิดขึ้นภายในโค้ดเบสของตนได้อย่างมีประสิทธิภาพ ดังนั้นจึงรับประกันประสบการณ์ผู้ใช้ที่ราบรื่นและเชื่อถือได้มากขึ้น

ใช้โครงสร้างการเขียนโปรแกรมแบบอะซิงโครนัส เช่น Promises และ async/await เพื่อลดปัญหาการโทรกลับแบบซ้อนในการจัดการเหตุการณ์ วิธีนี้นำเสนอวิธีแก้ปัญหาที่หรูหรากว่าเมื่อเปรียบเทียบกับการใช้เทคนิคการทำรังที่ยุ่งยาก

ขอแนะนำให้หลีกเลี่ยงการสร้างผู้ฟังจำนวนมากเกินไปสำหรับกิจกรรมเดียว เนื่องจากอาจทำให้เกิดปัญหาด้านประสิทธิภาพได้ ให้พิจารณาแบ่งเหตุการณ์และเชื่อมโยงเข้าด้วยกันตามลำดับเพื่อให้แน่ใจว่ามีประสิทธิภาพสูงสุด

สร้างแอปพลิเคชันด้วยสถาปัตยกรรมที่เหมาะสม

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

การเขียนโปรแกรมที่ขับเคลื่อนด้วยเหตุการณ์เป็นปรัชญาการออกแบบที่สามารถมีอิทธิพลอย่างลึกซึ้งต่อโครงสร้างและประสิทธิภาพของแอปพลิเคชัน หากโปรแกรมของคุณหรือส่วนประกอบใดๆ อาศัยเหตุการณ์ในการดำเนินการ การเขียนโปรแกรมที่ขับเคลื่อนด้วยเหตุการณ์ก็อาจคุ้มค่าที่จะพิจารณาเป็นแนวทางที่เหมาะสม