สามเณรถึง node.js อะไรคือข้อดีที่ได้รับจากการใช้ callback ในการทำกิจกรรม?


24

ฉันเป็น JavaScripter สามเณรและไม่มีความรู้ที่แท้จริงว่าเกิดอะไรขึ้นกับเครื่องยนต์ V8

ต้องบอกว่าฉันสนุกกับการจู่โจมยุคแรกของฉันในสภาพแวดล้อมของ node.js แต่ฉันพบว่าฉันกำลังใช้ events.EventEmitter () เป็นวิธีในการเปล่งเหตุการณ์ทั่วโลกเพื่อให้ฉันสามารถจัดโครงสร้างโปรแกรมของฉันให้พอดีกับผู้สังเกตการณ์ รูปแบบคล้ายกับสิ่งที่ฉันจะเขียนด้วยพูดในโปรแกรม Objective-C หรือ Python

ฉันพบว่าตัวเองทำสิ่งนี้อยู่เสมอ:

var events = require('events');

var eventCenter = new events.EventEmitter();

eventCenter.on('init', function() {
    var greeting = 'Hello World!';
    console.log('We're in the init function!);
    eventCenter.emit('secondFunction', greeting);
});

eventCenter.on('secondFunction', function(greeting) {
        console.log('We're in the second function!);
        console.log(greeting);
    eventCenter.emit('nextFunction');
});

eventCenter.on('nextFunction', function {
    /* do stuff */
});

eventCenter.emit('init');

ดังนั้นในความเป็นจริงฉันแค่สร้างรหัส 'async' node.js เป็นรหัสที่ทำสิ่งต่าง ๆ ตามที่ฉันคาดไว้ แต่ฉันกลับ "เขียนโค้ดถอยหลัง" ถ้ามันเหมาะสม จะมีความแตกต่างในการทำเช่นนี้ในลักษณะการโทรกลับหนักอย่างใดอย่างหนึ่งประสิทธิภาพการทำงานหรือปรัชญาที่ชาญฉลาด? มันจะดีกว่าที่จะทำสิ่งเดียวกันโดยใช้การโทรกลับแทนเหตุการณ์?


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

ฉันสับสนฉันไม่เห็น async อะไรในรหัสของคุณเพียงแค่เรียกใช้ฟังก์ชันที่เขียนด้วยวิธีที่ซับซ้อน
svick

คำตอบ:


27

สิ่งที่ดีเกี่ยวกับการโทรกลับคือไม่มีรัฐทั่วโลกที่นั่นและการส่งผ่านพารามิเตอร์ไปยังพวกเขานั้นเป็นเรื่องเล็กน้อย หากคุณมีฟังก์ชั่นdownload(URL, callback: (FileData)->void)คุณก็สามารถรู้ได้ว่ามันเป็นฟังก์ชั่นการสั่งซื้อขั้นสูงที่มีอยู่ในตัวเองซึ่งช่วยให้คุณสร้างฟังก์ชั่น "คว้าสิ่งนี้และทำสิ่งนั้น" คุณสามารถมั่นใจได้ว่าการไหลของรหัสของคุณตรงตามที่คุณคาดไว้เพราะไม่มีใครแม้แต่จัดการหมายเลขโทรกลับนั้นและการติดต่อกลับนั้นไม่ทราบอะไรเลยนอกจากพารามิเตอร์ที่กำหนดของฟังก์ชันหลัก ที่ทำให้มันเป็นโมดูลและง่ายต่อการทดสอบ

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

ในทางกลับกันกิจกรรมได้รับการออกแบบมาเพื่อแจ้งให้1..*ผู้ใช้ทราบถึงการเปลี่ยนแปลงสถานะ หากคุณเรียกใช้เหตุการณ์ "ดาวน์โหลดเสร็จสมบูรณ์" ในตอนท้ายdownload(URL)ซึ่งจะเปิดตัวprocessDownload()ที่รู้ว่าจะหาข้อมูลได้ที่ไหนคุณกำลังผูกการใช้งานของสิ่งต่าง ๆ ให้อยู่ในสถานะที่กว้างขึ้น คุณจะทำการดาวน์โหลดแบบขนานได้อย่างไร? คุณจัดการกับการดาวน์โหลดที่แตกต่างกันอย่างไร คือdownload(URL, eventId)สง่างาม? คือdownloadAndDoThing(URL)สง่างาม? แทบจะไม่

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

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


2

ฉันไม่เคยใช้เหตุการณ์ใน NodeJS แต่โดยทั่วไปสิ่งที่ฉันใช้เหตุการณ์ JS สำหรับลูกค้าคือการส่งสัญญาณว่ามีบางอย่างเกิดขึ้นเช่น AppointmentBookedEvent เพื่อให้ส่วนต่าง ๆ ของมุมมอง SPA สามารถตอบสนองต่อเหตุการณ์นั้นได้ (แสดงในไทม์ไลน์โหลด ในแผงควบคุม ฯลฯ )
แต่การใช้กิจกรรมเพื่อส่งสัญญาณวิธีการเสร็จสมบูรณ์อาจเป็นเส้นทางอันตรายในการเดินทาง คุณไม่สามารถพึ่งพาเหตุการณ์ที่จะมาถึงในลำดับเดียวกันกับที่พวกเขาถูกไล่ออกเพื่อที่จะนำไปสู่การสุ่มทุกประเภท ...
ไม่มีอะไรผิดปกติกับการใช้กิจกรรม แต่มีระดับความละเอียดที่คุณไม่ควรเข้าไป ; ถ้าคุณยึดติดกับโดเมน domain-ish นั่นก็ดี แต่การแจ้งเตือนว่าวิธีการเสร็จสิ้นนั้นละเอียดเกินไป


0

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

ดังนั้นeventCenterอาจปล่อย "init" ซึ่งวัตถุอื่นสามารถจัดการกับรหัสเริ่มต้นเป็นต้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.