Novice to node.js, lợi thế đạt được khi sử dụng các cuộc gọi lại qua các sự kiện là gì?


24

Tôi là một JavaScripter mới làm quen và không có kiến ​​thức thực sự về những gì diễn ra bên trong động cơ V8.

Phải nói rằng, tôi thực sự rất thích những bước đột phá đầu tiên của mình vào môi trường node.js nhưng tôi thấy rằng tôi liên tục sử dụng các sự kiện. mô hình tương tự như những gì tôi sẽ viết khi nói chương trình Objective-C hoặc Python.

Tôi thấy mình luôn làm những việc như thế này:

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');

Vì vậy, trong thực tế, tôi chỉ cấu trúc mã 'async' node.js thành mã thực hiện mọi thứ theo thứ tự tôi mong đợi, thay vào đó tôi là loại "mã hóa ngược" nếu điều đó hợp lý. Sẽ có bất kỳ sự khác biệt trong việc làm điều này theo cách gọi lại, nặng về hiệu suất hoặc khôn ngoan triết học? Có phải tốt hơn để làm điều tương tự bằng cách sử dụng các cuộc gọi lại thay vì các sự kiện?


Nếu bạn thấy khả năng đọc mã của mình bị ảnh hưởng do sử dụng nhiều các cuộc gọi lại, hãy xem xét việc sử dụng một khung để bọc việc sử dụng các cuộc gọi lại của bạn. Nó cần một chút điều chỉnh, nhưng những lời hứa thường có thể gỡ rối các cuộc gọi lại xấu xí. Nếu bạn đang sử dụng JQuery, bạn có thể sử dụng Trì hoãn . Một trong những khuôn khổ hứa hẹn đơn giản nhất là RSVP .
Brian

Tôi bối rối, tôi không thấy bất cứ điều gì không đồng bộ trong mã của bạn, chỉ là các cuộc gọi chức năng được viết theo cách quá phức tạp.
Svick

Câu trả lời:


27

Điều hay ho về các cuộc gọi lại là không có trạng thái toàn cầu ở đó và việc truyền tham số cho chúng là chuyện nhỏ. Nếu bạn có một chức năng download(URL, callback: (FileData)->void)thì bạn có thể biết đó là một chức năng bậc cao độc lập, về cơ bản cho phép bạn xây dựng một chức năng "lấy cái này và làm điều đó". Bạn có thể chắc chắn luồng mã của mình chính xác như bạn mong đợi, bởi vì thậm chí không ai khác có thể xử lý cuộc gọi lại đó và cuộc gọi lại đó không biết gì về các tham số đã cho của hàm cha. Điều đó làm cho nó mô-đun và dễ dàng để kiểm tra.

Nếu bây giờ bạn muốn tải xuống 5 tệp song song và thực hiện các thao tác khác nhau, bạn chỉ cần tắt năm chức năng này với các chức năng gọi lại thích hợp. Trong một ngôn ngữ có cú pháp hàm ẩn danh tốt, điều này có thể cực kỳ mạnh mẽ.

Mặt khác, các sự kiện được thiết kế nhiều hơn để thông báo cho 1..*người dùng về một số thay đổi trạng thái. Nếu bạn thực hiện một sự kiện "tải xuống hoàn tất" vào cuối download(URL), sẽ khởi chạy processDownload()để biết nơi tìm dữ liệu, bạn đang buộc việc triển khai mọi thứ của mình vào một trạng thái lớn hơn. Làm thế nào để bạn tải xuống song song bây giờ? Làm thế nào để bạn xử lý các tải xuống khác nhau khác nhau? Là download(URL, eventId)thanh lịch? Là downloadAndDoThing(URL)thanh lịch? Khó khăn.

Tất nhiên, như với tất cả mọi thứ, bạn đang thực hiện đánh đổi. Callbacks lồng nhau có thể làm cho tự thực hiện mã khó hiểu hơn, và sự thiếu hỗ trợ truy cập dễ dàng toàn cầu làm cho nó một lựa chọn tốt cho bất cứ điều gì mà bạn làm có một 1..*mối quan hệ giữa nhà sản xuất và người tiêu dùng. Bạn có một thời gian khó khăn hơn để truyền dữ liệu xung quanh, nhưng nếu bạn có thể thoát khỏi việc không có trạng thái bổ sung thì đó thường là một lợi ích.

Bất kể. Bạn đang mã hóa trong node.js trong đó các cuộc gọi lại là thành ngữ và ngôn ngữ và thư viện được thiết kế xung quanh việc sử dụng chúng. Cho dù bạn thấy lợi thế trong thiết kế này hay thiết kế khác, tôi nghĩ hầu như luôn luôn đúng rằng viết mã thành ngữ bằng bất kỳ ngôn ngữ nào sẽ có sự hỗ trợ lớn hơn nhiều và làm cho cuộc sống của bạn dễ dàng hơn nhiều so với cố gắng phá vỡ nó.


2

Tôi chưa bao giờ sử dụng các sự kiện trong NodeJS, nhưng nói chung, những gì tôi sử dụng các sự kiện JS của máy khách là báo hiệu rằng đã xảy ra sự cố, ví dụ như AppointmentBookedEvent, để các phần khác nhau của chế độ xem SPA có thể phản ứng với điều đó (hiển thị trong dòng thời gian, tải nó trong một bảng điều khiển, vv).
Nhưng sử dụng các sự kiện để báo hiệu một phương pháp đã hoàn thành có thể là một con đường nguy hiểm để đi du lịch. Bạn không thể dựa vào các sự kiện để đến theo thứ tự chúng bị bắn, do đó có thể dẫn đến tất cả các loại ngẫu nhiên ...
Không có gì sai khi sử dụng các sự kiện, nhưng có một mức độ chi tiết nhất định mà bạn không nên theo ; nếu bạn dính vào các sự kiện tên miền, điều đó tốt. Nhưng thông báo rằng các phương pháp đã hoàn thành là quá chi tiết.


0

Một cái gì đó bạn có thể khám phá là việc sử dụng các sự kiện bên ngoài đối tượng đang phát ra chúng. Trong ví dụ của bạn, eventCenterxuất hiện cả phát ra và xử lý các sự kiện riêng của nó. Xem xét cách cấu trúc ứng dụng của bạn có thể thay đổi nếu các đối tượng khác bắt đầu xử lý các sự kiện.

Vì vậy, eventCentercó thể phát ra "init", mà các đối tượng khác sau đó có thể xử lý để thực hiện mã khởi động, v.v.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.