Người nghe sự kiện có nên được gọi nếu được đính kèm sau khi sự kiện đã được kích hoạt không?


8

Người nghe sự kiện có nên được gọi nếu nó được đính kèm sau khi sự kiện đã được kích hoạt? Nếu sự kiện sẽ chỉ bị sa thải một lần thì sao?

Ví dụ đầu tiên xuất hiện trong đầu là readysự kiện trong jQuery. Đoạn mã sau, khi được đánh giá sau khi trang được tải, vẫn sẽ gọi lại cuộc gọi lại:

$(document).ready(function () {
    console.log("Works.");
});

Thay thế cho hành vi này có thể là cờ được đặt khi trang được tải, buộc người tiêu dùng API phải kiểm tra xem sự kiện đã xảy ra chưa và hành động tương ứng:

if (document.readyState == "complete") {
    console.log("Works.");
} else {
    $(document).ready(function () {
        console.log("Works.");
    });
}

Mặc dù ví dụ trên nằm trong bối cảnh tải trang web, nơi mọi thứ và mọi thứ (thường) cần phải xảy ra sau khi trang được tải hoàn toàn, các đối số tương tự có thể được tạo cho bất kỳ thành phần nào trong ứng dụng có các sự kiện "đơn lẻ" ( load, start, end, vv). Một ví dụ về một thành phần có thể là một bản đồ với một loadsự kiện kích hoạt để chỉ định rằng bản đồ đã được tải :

map.on("load", function () {
    console.log("The map has loaded.");
});

Ví dụ trên xuất phát từ API ArcGIS cho JavaScript, trong đó sự kiện đó chỉ được kích hoạt một lần và nếu người tiêu dùng "chờ" bản đồ tải sau khi bản đồ đã được tải, người nghe sẽ không bao giờ được gọi. Kết quả mong muốn yêu cầu kiểm tra trạng thái của bản đồ trước khi người nghe được đính kèm:

if (map.loaded) {
    console.log("The map has loaded.");
} else {
    map.on("load", function () {
        console.log("The map has loaded.");
    });
}

Hành vi nào là đúng, yêu cầu người tiêu dùng kiểm tra xem một sự kiện đã được kích hoạt hay luôn gọi lại cuộc gọi lại?


5
Bạn có thể quan tâm đến Phần mở rộng phản ứng Subjectso với ReplaySubject, trong đó phần sau phát lại các sự kiện trước đó cho người đăng ký muộn trong khi phần trước thì không. Đó là, những người tạo ra Rx đã mô hình hóa cả hai hành vi thay vì quyết định một hành vi xác định. - Và trong khi các liên kết ở trên đi đến tài liệu của phiên bản Rx '.NET, thì cũng có Rx cho JavaScript .
stakx

Câu trả lời:


19

Điều đó phụ thuộc vào việc nó thực sự là Thông báo Sự kiện hay Thông báo Nhà nước (đó là những gì đã sẵn sàng). Nếu đó là một sự kiện, thì bạn đừng nói với người nghe về tất cả các sự kiện trước đó. Nếu đó là Thông báo trạng thái, thì bạn báo cho họ biết ngay sau khi họ đăng ký và bạn đang ở trạng thái được chỉ định.

Một chút khó khăn sẽ là nơi nó có thể là một trạng thái hoặc một sự kiện, tùy thuộc vào cách bạn nhìn vào nó - tệ nhất, điều đó được giải thích bởi tài liệu. Tốt nhất bạn chọn một cái tên hay để nói rõ ý của bạn.


2
+1, cũng để đề cập đến thông báo trạng thái. Thông báo trạng thái là IMO gần với tương lai và việc xử lý các cuộc gọi lại của họ, ví dụ như trong Scala ( docs.scala-lang.org/overview/core/futures.html ).
Giorgio

Thật thú vị, tôi đã không nghĩ về nó như thế. Bạn sẽ phân loại load, starthoặc endgiống readynhư một thông báo trạng thái?
Whymarrh

@Whymarrh: Điều đó sẽ phụ thuộc vào bối cảnh, nhưng những âm thanh này giống như các sự kiện đối với tôi. Tôi có xu hướng đặt tên thông báo trạng thái là câu hỏi ... sẵn sàng? đã bắt đầu? đang chạy? nhưng tất nhiên bạn có thể phải điều chỉnh nó phù hợp với quy ước đặt tên hiện có.
jmoreno

3
Dường như với tôi như các sự kiện có thể được hiểu là một cái gì đó xảy ra một lần để thay đổi trạng thái. Điều này có nghĩa là chúng rất ngắn, thực tế là một khoảnh khắc. Mặt khác, một trạng thái được kéo dài và bao gồm nhiều khoảnh khắc. loadkhông phải là một sự kiện cũng không phải là một nhà nước. loadingStartedlà một sự kiện và loadinglà một nhà nước.
Jeroen Vannevel

5

Nói chung, không .

Người nghe sự kiện không nên được gọi nếu họ được đính kèm sau khi sự kiện đã được kích hoạt. "Bạn đang ngủ bạn bị mất."

Có một số ngoại lệ quan trọng. $(document).ready()có lẽ là ví dụ hoàn hảo - một sự kiện mà trước đó toàn bộ bối cảnh đánh giá không được thiết lập một cách đáng tin cậy hoặc hoàn toàn, và hoạt động như một điểm đánh dấu "xử lý chức năng đầy đủ bắt đầu từ đây".

Tuy nhiên, nếu bạn đặt quy tắc rằng trình xử lý sự kiện sẽ được kích hoạt ngay cả khi nó được cài đặt và / hoặc kích hoạt sau khi sự kiện xảy ra, thì bạn đã tuyên bố rằng tất cả các sự kiện nên hoặc phải được đệm từ đầu đến cuối chương trình chạy, cho mọi sự kiện có thể tưởng tượng được. Khác, có thể có các trình xử lý sự kiện được thiết lập trong một số sự kiện, ở đâu đó trên đường, rằng bạn không có đủ thông tin để biết liệu bạn có nên bắn khi nó được thiết lập hay không. Điều đó có nghĩa là bạn phải ghi lại mọi nguồn sự kiện có thể và đệm vô hạn cho mỗi một trong số chúng. Điều đó đòi hỏi xử lý sự kiện từ đánh giá lười biếng (và tất cả các lợi ích hiệu suất của nó) suốt quá trình đánh giá háo hứcvà vào bất cứ thứ gì ở phía xa của quang phổ. Đánh giá điên cuồng dựa trên các giả định thảm khốc về những sự kiện có thể cần phải được xử lý sau này?

Các sự kiện có xu hướng thoáng qua và nhiều. Đặt quy tắc yêu cầu mỗi bộ đệm, nhưng không giới hạn, về khả năng cuối cùng chúng sẽ được gõ - đó là tự sát hiệu suất. Hơn nữa, không có yêu cầu lớn để làm như vậy, vì người xử lý thường có thể được thiết lập sớm trong cuộc sống chương trình.

Các ngoại lệ cho quy tắc là các trường hợp cạnh - tải tài liệu hoặc hệ thống con, ví dụ, đó là những sự kiện thiết yếu, duy nhất, không thể nắm bắt hoặc có thể xử lý được. Điều này rất gần với các sự kiện "singleton" của bạn. Một nhóm khác có thể cần xử lý đặc biệt là các lỗi đáng kể, sự kiện bảo mật hoặc thay đổi trạng thái có nhu cầu đặc biệt được gắn cờ ngay cả khi không có người đăng ký cờ tại thời điểm sự kiện xảy ra.

Một lưu ý cuối cùng: Một sự kiện "sẵn sàng" khác biệt một cách tinh tế với sự kiện "tải". Mặc dù chúng thường không được phân biệt rõ ràng (ví dụ như HTML onloadvà jQuery $(document).ready()được coi là rất giống nhau về mặt logic) và cả hai đều báo hiệu sự sẵn có của tài nguyên hoặc môi trường xử lý - nhưng chúng không hoàn toàn giống nhau. Tải (hoặc hoàn thiện nó) là một sự kiện có thật - một cái gì đó được báo hiệu từ cơ sở hạ tầng đến người tiêu dùng. Sự sẵn sàng, tuy nhiên, là nhiều điểm hẹnvề cơ sở hạ tầng đang tải tài nguyên / môi trường và người tiêu dùng đang chuẩn bị sẵn sàng để tiêu thụ / tận dụng sự sẵn có đó. Sự sẵn sàng xuất hiện sau khi tải và là một trong những sự kiện / điểm phối hợp đặc biệt được chỉ định phải được coi là có thể xếp hàng vì bạn không thể nắm bắt nó theo bất kỳ cách nào khác. Tuy nhiên, có một vài trường hợp rất đặc biệt, tuy nhiên, điều đó không có nghĩa là mọi sự kiện đều có thể được điều chỉnh bởi một posteriori .


Erm, ý bạn là "onload" của html?
StarWeaver

@ StarWeaver Cảm ơn. Không chắc chắn nếu tôi trượt hoặc tự động quá tham vọng của tôi đã làm, nhưng bạn hoàn toàn đúng. Đã sửa.
Jonathan Eunice

NP, tôi không phải là tất cả với bài viết html 4 nhưng nghe có vẻ kỳ quặc. Giải thích tốt đẹp, quá.
StarWeaver
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.