EventEmitter 事件系統
EventEmitter 是 Node.js 的內建模組,不需要另外安裝。
import EventEmitter from "node:events"; // node: 前綴代表是 Node.js 內建
基本用法
一個簡單的事件發布/訂閱系統:
const emitter = new EventEmitter();
// 訂閱:聽到 "process" 事件就執行這個 function
emitter.on("process", () => {
console.log("收到事件了!");
});
// 發布:觸發 "process" 事件
emitter.emit("process");
// → 印出 "收到事件了!"
Python 類比:最接近的是簡單的 observer pattern(手刻),或第三方套件
blinker:# 手刻版(最接近 EventEmitter 的結構)class EventEmitter:def __init__(self):self.listeners = {}def on(self, event, callback):self.listeners.setdefault(event, []).append(callback)def emit(self, event, *args, **kwargs):for cb in self.listeners.get(event, []):cb(*args, **kwargs)emitter = EventEmitter()emitter.on("process", lambda: print("收到事件了!"))emitter.emit("process")
事件名稱是動態的
事件不需要預先定義,它是動態的。你 emit 什麼字串,on 監聽什麼字串,就配對上了。
emitter.on("taskComplete", async () => { ... });
emitter.emit("taskComplete");
emitter.on("pizza", () => console.log("好吃"));
emitter.emit("pizza"); // → "好吃"
Python 類比:就像 Python 的 dict,key 不用預先定義:
listeners = {}listeners["process"] = some_functionlisteners["shutdown"] = another_function
on vs once
once 跟 on 的差別只有一個:只執行一次。
// on — 每次 emit 都會執行
emitter.on("tick", () => console.log("hi"));
emitter.emit("tick"); // → "hi"
emitter.emit("tick"); // → "hi"(無限次)
// once — 只執行第一次,之後自動取消註冊
emitter.once("shutdown", () => console.log("bye"));
emitter.emit("shutdown"); // → "bye"
emitter.emit("shutdown"); // → (沒反應了)
Python 類比:
threading.Event的wait()搭配set()可以做到類似的一次性觸發:import threadingshutdown_event = threading.Event()def on_shutdown():shutdown_event.wait() # 等待直到 set()print("bye")threading.Thread(target=on_shutdown).start()shutdown_event.set() # 觸發一次,之後 wait() 不再阻塞