Press enter to see results or esc to cancel.

Event Emitter – X gọi, 500 anh em trả lời

Chào các bác ,lâu rồi em không viết bài gì cả, bận quá 

Hôm nay mình tìm hiểu về Javascript tí nhề. Bài này mình sẽ nói về Event Emitter.

Vậy Event Emitter là gì?

Event Emitter hoạt động kiểu giống như câu mình ghi ở “Tít” – “X gọi, 500 anh em trả lời. Tuởng tuợng như vầy nhé

maxresdefault-1

Halloween vừa dắt gái đi chơi về, bỗng dưng có một bầy thanh niên “Tha thu” đầy nguời nhảy vào đe doạ , đòi “va chạm” với bạn gái của bạn xíu . Con này thì mới quen, đầu tư chưa lấy lại vốn thì chưa thế tụi nó đụng vào được . Vì thế bạn nhất quyết không cho thằng nào đụng chạm vào, khổ nỗi tụi nó đông và hung hãn quá, giờ sao ??? May quá nhớ ra mấy thằng chiến hữu cũng có máu mặt, giờ này FA chắc đang ngồi nhà DOTO, thế là bạn cầm con điện thoại ra alo tụi nó like a boss 

Thằng A

Alo… Mày đang ở đâu thế, đến 69 đường XXX cứu tao với.

T đang tiêu chảy , đếu kíu được mày đâu. Gọi thằng B coi

ngoibo

Thằng B

Alo… Mày đang ở đâu thế, đến 69 đường XXX cứu tao với.

Mày bảo tụi nó đợi tao 5′, để tao gọi 500 anh em ra cứu bạn gái mày 

Đấy Event Emitter hoạt động giống như câu chuyện mình nói. Khi một đối tương (Object – là bạn đấy) gặp phải một sự kiện gì đấy thì bạn hét lên một thông điệp (Emit). Những thằng nghe đuợc thông điệp của bạn (Listener) sẽ nhận thông điệp ấy và xử lý tuỳ từng thằng khác nhau. Như ở trên, khi bạn truyền thông điệp đi “Mày đang đâu thế, đến đuờng 69 đuờng XX cứu tao với” thằng A đang tiêu chảy thì nó lơ bạn luôn, còn thằng B sẽ gọi 500 anh em tới cứu bạn.

Thế là đã mường tượng được Event Emitter là gì rồi nhé 

Code thử xem sao

Đầu tiên là tạo class Event Emitter

class EventEmitter {
    constructor() {
        this.listener = []
    }
    addListener(event, listener) {
        if (this.listener[event]) {
            this.listener[event].push(listener)
        } else {
            this.listener[event] = Array(listener)
        }
        console.log ("Added new listener")
        console.log (this.listener)
        return {event: event, index: this.listener[event].indexOf(listener)}
    }
    removeListener(listenerInfo) {
        this.listener[listenerInfo.event].splice(listenerInfo.index, 1)
        console.log ("Removed a listener")
        console.log (this.listener)
    }
    emit(event, arg) {
        if (this.listener[event]) {
            this.listener[event].reverse().forEach((x) => x(arg))
        }
        console.log ("Emmitted #{event}")
    }
}

Trong class EventEmitter của chúng ta có 4 method chính là Constructor, addListener, removeListener, và emit

Constructor

constructor() {
    this.listener = []
}

Thằng này đơn giản, có nhiệm vụ khởi tạo một array chứa danh sách các listener tùy theo event là gì thôi,

addListener

    addListener(event, listener) {
        if (this.listener[event]) {
            this.listener[event].push(listener)
        } else {
            this.listener[event] = Array(listener)
        }
        console.log ("Added new listener")
        console.log (this.listener)
        return {event: event, index: this.listener[event].indexOf(listener)}
    }

Thằng này thì thêm một chiến hữu trong 500 anh em của bạn vào danh bạ. Khi nào cần chỉ việc cầm dt lên alo nó

removeListener

    removeListener(listenerInfo) {
        this.listener[listenerInfo.event].splice(listenerInfo.index, 1)
        console.log ("Removed a listener")
        console.log (this.listener)
    }

Có thêm thì phải có xoá thôi . Con Nokia 1280 chỉ lưu dc 500 số thì các bác phải xoá bớt đi những thằng bê đê dành chỗ cho các anh chuẩn men khác . Input của hàm này là output của hàm addListener mình nói bên trên

emit

    emit(event, arg) {
        if (this.listener[event]) {
            this.listener[event].forEach((x) => x(arg))
        }
        console.log ("Emitted "+event)
    }

Cái này là các bác nè, khi gọi hàm này tuơng đương các bác hét lên hoặc nhắn tin với một nhóm trong danh bạ dt. Thằng nào nhận dc tin nhắn của các bác thì nó xử lý ra sao tuỳ tụi nó, các bác không biết được (phần này khác với ví dụ mình nói ở trên một xíu )

When the EventEmitter object emits an event, all of the functions attached to that specific event are called synchronously. Any values returned by the called listeners are ignored and will be discarded.Nodejs Document

Thử nha

Tạo đối tượng là bản thân ta

let cuThanh = new EventEmitter

Thêm tụi bạn vào danh bạ

let thangA = cuThanh.addListener("GOI500AE", () => {
    console.log ("A: T đang tiêu chảy, đếu kíu được mày đâu. Gọi thằng B coi")
})
let thangB = cuThanh.addListener("GOI500AE", () => {
    console.log ("B: Mày bảo tụi nó đợi tao 5′, để tao gọi 500 anh em ra cứu bạn gái mày.")
})

Ở trên, ta định nghĩa thông điệp là GOI500AE, các listener chỉ hoạt động khi nó nghe được đúng thông điệp mà chúng ta hét lên (emit). Vậy là có 2 thằng bạn, luôn sẵn sàng trả lời khi cuThanh hét lên GOI500AE. Thông điệp thì các bác nên để ngắn gọn, xúc tích xíu nhá.

Bây giờ hét thử lên nha

cuThanh.emit("GOI500AE")

Chúng ta nhận được ngay

"A: T đang tiêu chảy, đếu kíu được mày đâu. Gọi thằng B coi"
"B: Mày bảo tụi nó đợi tao 5′, để tao gọi 500 anh em ra cứu bạn gái mày."
Emitted GOI500AE

Sau lần gọi đồng đội đầu tiên, thấy thằng A chơi chó quá, bạn bè cần mà lại ngồi trong wc. Bạn quyết định xoá nó khỏi danh bạ, “Tao đéo cần mày nữa, lộn cái bàn, tốn tiền điện thoại của bố” 

loncaiban

cuThanh.removeListener(thangA)

Bây giờ khi bạn hét lên “GOI500AE” thì chỉ còn lại thằng B trả lời thôi

"B: Mày bảo tụi nó đợi tao 5′, để tao gọi 500 anh em ra cứu bạn gái mày."
Emitted GOI500AE

Đấy, mình đã hiện thực cho các bác cách hiện thực của Event Emitter. Thực ra Event Emitter không quá xa lạ với các bác đã nhảy vảo Javascript.

$('button').on('click', () => {
    alert ("You clicked a button")
})

Quen chưa, rồi cả các sự kiện page onLoad, onUnload, onHover,… nữa. Ngoài ra ở Nodejs nếu dụng package request thì các bác cũng bắt gặp nó ở đâu đó 

Về Event Emitter

Cái việc sử dụng Event Emitter này giúp các bác lập trình theo kiểu gọi là: Lập trình hướng sự kiện, mình thấy rất là phổ biến ở thế giới Javascript. Có khác biệt là tên gọi của các method thôi nên khiến bạn khó nhận ra. Vậy lợi hại của việc lập trình theo hướng sự kiên là gì? Mình cũng méo biết , mới tìm hiểu thôi. Tại vì đang tìm hiểu vẻ Redux thấy nó hiện thực một Event Emitter kiểu kiểu như code ở trên của mình.

P/S: Nếu các bác chỉ cần hiện thực Event Emitter một cách đơn giản thì theo mình code ở trên là đủ rồi. Nó cho phép truyền cả thông số khi emit nữa (sử dụng làm sao thì các bác tự đọc code mò mẫm đi nhá, em luời ví dụ lắm). Còn nếu muốn nhu cầu phức tạp hơn thì nên sử dụng một số thư viện có sẵn (nếu các bác không muốn đào sâu nghiên cứu, chỉ cần down về là chạy thôi). Nodejs có hỗ trợ sẵn EventEmitter, còn nếu muốn sử dụng ở brower thì các bác search đi nhé, đầy 

Code của toàn bộ bài viết.

Các bác node EventEmitter.js để chạy thử nhé

Like
Like Love Haha Wow Sad Angry
61
Comments

6 Comments

Bách Văn Khoa

bài viết rất hay :D, tiện đây thím cho em hỏi có cách nào để cho mình là client download được image được parse từ server ra file php không. Ví dụ như cái captcha của viettel này.
http://www.vietteltelecom.vn/index.php/captcha
Em gửi request đến trang này nhưng mà content response nó chỉ có vài cái tag html thôi :sosad:, em nghĩ là do request không phải là từ browser nên server nó không trả về hình ảnh, vì thế nên em cố gắng tìm cách set header của requests sao cho server tưởng request đến từ browser nhưng mà không được :sosad:

Minh Thành

Đầu tiên bác request thưòng tới link captcha là
http://www.vietteltelecom.vn/index.php/captcha
Trong response sẽ có một đoạn JavaScript như sau
document.cookie="D0N=3fa37404f99a1568ed9766df100184d0"+"; path=/";

Kèm theo một giá trị cookie có sẵn được set bằng Javascript. Có lẽ server đó sẽ kiểm trả xem đã tồn tại cookie đó thôi. Đuơng nhiên chỉ có brower là hiểu dc JS và thực thi nó. Nên bác fải đọc chuỗi cookie đó, thêm vào header kèm theo header có sẵn lúc đầu là sẽ ra captcha
Nếu bác sài demo thì mình có demo cho bác
https://gist.github.com/nlug/f4aba016d5605671bca3e55fcf5fa851

P/S: Bác đòi chơi cả Viteo hả? mạnh thế

Bách Văn Khoa

em chưa dám chơi với Viettel :gach: chẳng qua là đang học python cái đoạn download file, file khác có link thì đơn giản rồi nhưng mà với image được parse ra như này thì chưa biết giải quyết sao nên hỏi thím thôi :gach: Cám ơn thím đã chỉ, em sẽ nghiên cứu translate cái demo của thím sang python :3
Yêu thím :beauty:

trung khong

Bài viết hay , dễ hiểu. Cảm ơn cu Thanh 😀

Minh Thành

thanks bác 😀

Dao Duc Hoang

Viết hay lắm cám ơn bạn nhe


Leave a Comment