ข้อมูลเบื้องต้นเกี่ยวกับการเขียนโปรแกรมที่ขับเคลื่อนด้วยเหตุการณ์ใน Node.js
ประเด็นที่สำคัญ
การเขียนโปรแกรมที่ขับเคลื่อนด้วยเหตุการณ์เป็นแนวทางที่เหมาะสำหรับการพัฒนาแอปพลิเคชันเชิงโต้ตอบ โดยเฉพาะอย่างยิ่งแอปพลิเคชันที่มีส่วนต่อประสานกราฟิกกับผู้ใช้ (GUI) เนื่องจากช่วยให้โค้ดตอบสนองต่อการโต้ตอบของผู้ใช้ในลักษณะที่คาดเดาไม่ได้ ความยืดหยุ่นนี้รองรับวิธีการที่หลากหลายที่ผู้ใช้สามารถโต้ตอบกับแอป และมอบประสบการณ์การตอบสนองที่ตรงกับความต้องการของพวกเขาได้อย่างราบรื่น
การเขียนโปรแกรมที่ขับเคลื่อนด้วยเหตุการณ์ได้กลายเป็นวิธีการที่แพร่หลายในเว็บแอปพลิเคชัน โดยที่ตัวฟังเหตุการณ์จะถูกเปิดใช้งานเมื่อผู้ใช้โต้ตอบกับ Document Object Model (DOM)
การรวมการเขียนโปรแกรมตามเหตุการณ์ใน Node.js สามารถทำได้ได้อย่างราบรื่นผ่านการใช้คลาส EventEmitter ซึ่งอำนวยความสะดวกในการสร้างเหตุการณ์ที่ปรับแต่งและการแนบตัวจัดการเหตุการณ์เพื่อการจัดการที่เหมาะสม
เมื่อพัฒนาแอปพลิเคชันซอฟต์แวร์ การเลือกกระบวนทัศน์การเขียนโปรแกรมที่เหมาะสมถือเป็นการตัดสินใจที่สำคัญที่ต้องทำ ในที่สุดกระบวนทัศน์มีอิทธิพลต่อโครงสร้างและการจัดระเบียบของโค้ดตลอดจนประสิทธิภาพและการบำรุงรักษา ดังนั้นจึงเป็นเรื่องสำคัญที่จะต้องพิจารณาอย่างรอบคอบว่ากระบวนทัศน์ใดที่สอดคล้องกับข้อกำหนดและเป้าหมายเฉพาะของโครงการมากที่สุด ก่อนที่จะตัดสินใจใช้แนวทางเฉพาะ
การเขียนโปรแกรมที่ขับเคลื่อนด้วยเหตุการณ์ ซึ่งมีคุณลักษณะเฉพาะคือการตอบสนองต่อเหตุการณ์อะซิงโครนัสที่เกิดขึ้นในลำดับที่ไม่สามารถคาดเดาได้ เหมาะอย่างยิ่งสำหรับแอปพลิเคชันที่ต้องการปฏิสัมพันธ์กับผู้ใช้ และมักพบภายในอินเทอร์เฟซผู้ใช้แบบกราฟิก แทนที่จะเป็นโปรแกรมบรรทัดคำสั่งหรือการเข้ารหัสระบบแบบฝัง
กิจกรรมคืออะไร?
เหตุการณ์อาจถูกสร้างแนวความคิดว่าเป็นอินสแตนซ์ของการดำเนินการที่เริ่มต้นโดยโปรแกรมหรือสิ่งเร้าที่กระตุ้นให้เกิดปฏิกิริยาจากซอฟต์แวร์ ซึ่งจากนั้นจะถูกระบุและจัดการโดยส่วนประกอบการทำงานที่กำหนดภายในโค้ด โดยทั่วไปแล้ว ผู้ใช้หรือระบบเองจะกระตุ้นให้เกิดเหตุการณ์ โดยแจ้งให้โค้ดกำหนดขั้นตอนเฉพาะเพื่อประมวลผลผลลัพธ์
ในขอบเขตของการเขียนโปรแกรมคอมพิวเตอร์ เหตุการณ์พื้นฐานจะแสดงตัวอย่างโดยกระบวนการกดปุ่มบนแป้นพิมพ์เพื่อดำเนินการงานเฉพาะ เมื่อการดำเนินการนี้เกิดขึ้น จะทำให้เกิดเหตุการณ์ที่เรียกว่า"เหตุการณ์"ซึ่งต่อมาจะเปิดใช้งานรูทีนย่อยที่เรียกว่า"ผู้ฟัง"หรือ"ตัวจัดการ"
การเขียนโปรแกรมที่ขับเคลื่อนด้วยเหตุการณ์คืออะไร?
การเขียนโปรแกรมที่ขับเคลื่อนด้วยเหตุการณ์สามารถกำหนดลักษณะเป็นแนวทางเฉพาะในการพัฒนาซอฟต์แวร์ โดยที่ความก้าวหน้าของการดำเนินงานของแอปพลิเคชันนั้นขึ้นอยู่กับเหตุการณ์หรือเหตุการณ์เฉพาะ แทนที่จะยึดติดกับลำดับที่กำหนดไว้ล่วงหน้าและเป็นเส้นตรง
กระบวนทัศน์เฉพาะนี้ใช้กันโดยทั่วไปในการพัฒนาอินเทอร์เฟซผู้ใช้และแอปพลิเคชันแบบเรียลไทม์ โดยที่การกระทำของผู้ใช้จะทำหน้าที่เริ่มต้นการตอบสนองที่สอดคล้องกันจากระบบ
ในบริบทของการพัฒนาเว็บแอปพลิเคชัน การใช้ตัวฟังเหตุการณ์ได้กลายเป็นแนวทางที่นำมาใช้อย่างกว้างขวาง เนื่องจากถูกกระตุ้นเพื่อตอบสนองต่อการโต้ตอบของผู้ใช้กับ Document Object Model (DOM)
ภาพประกอบข้างต้นสรุปกลไกพื้นฐานของการเขียนโปรแกรมที่ขับเคลื่อนด้วยเหตุการณ์ ซึ่งเมื่อเกิดเหตุการณ์ขึ้น ช่องเหตุการณ์ที่เกี่ยวข้องจะถูกทริกเกอร์ให้ส่งเหตุการณ์ดังกล่าวไปยังผู้ฟังที่ได้รับมอบหมายเพื่อประมวลผล
การเขียนโปรแกรมที่ขับเคลื่อนด้วยเหตุการณ์ใน 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 เราสามารถคาดหวังได้ว่าจะได้เห็นการแสดงภาพที่คล้ายกับกราฟิกที่ปรากฎ:
ตัวอย่างที่กล่าวมาข้างต้นใช้เพื่อแสดงความก้าวหน้าตามลำดับเวลาของผู้ฟังเหตุการณ์ ซึ่งเป็นไปตามลำดับการลงทะเบียนที่พวกเขาเข้าร่วม
คลาส 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 เพื่อลดปัญหาการโทรกลับแบบซ้อนในการจัดการเหตุการณ์ วิธีนี้นำเสนอวิธีแก้ปัญหาที่หรูหรากว่าเมื่อเปรียบเทียบกับการใช้เทคนิคการทำรังที่ยุ่งยาก
ขอแนะนำให้หลีกเลี่ยงการสร้างผู้ฟังจำนวนมากเกินไปสำหรับกิจกรรมเดียว เนื่องจากอาจทำให้เกิดปัญหาด้านประสิทธิภาพได้ ให้พิจารณาแบ่งเหตุการณ์และเชื่อมโยงเข้าด้วยกันตามลำดับเพื่อให้แน่ใจว่ามีประสิทธิภาพสูงสุด
สร้างแอปพลิเคชันด้วยสถาปัตยกรรมที่เหมาะสม
เมื่อสร้างซอฟต์แวร์ การตัดสินใจเลือกสถาปัตยกรรมและการออกแบบที่มีข้อมูลครบถ้วนเป็นสิ่งสำคัญอย่างยิ่ง เพื่อหลีกเลี่ยงข้อผิดพลาดที่อาจเกิดขึ้นในสายการผลิต การไม่ปฏิบัติตามกลยุทธ์การพัฒนาที่ดีอาจนำไปสู่ผลลัพธ์ที่ไม่พึงประสงค์สำหรับการสมัครของคุณ
การเขียนโปรแกรมที่ขับเคลื่อนด้วยเหตุการณ์เป็นปรัชญาการออกแบบที่สามารถมีอิทธิพลอย่างลึกซึ้งต่อโครงสร้างและประสิทธิภาพของแอปพลิเคชัน หากโปรแกรมของคุณหรือส่วนประกอบใดๆ อาศัยเหตุการณ์ในการดำเนินการ การเขียนโปรแกรมที่ขับเคลื่อนด้วยเหตุการณ์ก็อาจคุ้มค่าที่จะพิจารณาเป็นแนวทางที่เหมาะสม