Pattern trong hệ sinh thái Node.js
Node.js, Redux và XState minh hoạ các pattern hướng sự kiện và quản lý state ở quy mô lớn.
| Pattern | Dự án | Ở đâu | Tác dụng |
|---|---|---|---|
| Observer / Pub-Sub | Node.js | lib/events.js | EventEmitter — nền tảng của kiến trúc hướng sự kiện trong Node |
| Observer / Pub-Sub | Redux | createStore.ts | subscribe() + dispatch() — thông báo thay đổi state |
| State Machine | XState | StateMachine.ts | Thư viện finite state machine tiêu chuẩn ngành |
| Backpressure | Node.js | writable.js | writeOrBuffer() — kiểm soát luồng highWaterMark + sự kiện drain |
| Iterator / Đánh giá lười | Node.js | lib/internal/streams/ | Async iterator cho stream — for await (const chunk of stream) |
| Retry Backoff | Node.js | dns, http | Retry phân giải DNS với backoff cấp số nhân |
| Dependency Graph | pnpm | graph-sequencer | Sắp xếp topo các package workspace để xác định thứ tự build |
| Rate Limiter | Express | express-rate-limit | Middleware token bucket cho rate limit API |
| Circuit Breaker | opossum | lib/circuit.js | Circuit breaker Node.js cho phục hồi microservice |
| Event Loop | Node.js (libuv) | deps/uv/src/unix/core.c | uv_run() — ghép kênh I/O đơn luồng qua epoll/kqueue |
| Middleware Chain | Koa.js | koa-compose | Ghép middleware thành pipeline mô hình hành tây với async/await |
Cách chúng kết hợp: Một request HTTP
Khi server Express/Koa xử lý một request, các pattern kết hợp từ lớp mạng cho tới response:
Incoming HTTP request▼libuv's uv_run() picks up the socket event from epoll/kqueue. The request is dispatched to the JS callback on the main thread. No threads blocked.
express-rate-limit checks the token bucket. If the client exceeded their quota, respond 429 immediately.
Koa-compose runs middleware in onion order: auth → validate → handler → log. Each calls next() to proceed or short-circuits on error.
The handler emits events (e.g., 'userCreated'). EventEmitter notifies all subscribers: cache invalidation, audit log, notification service — all decoupled.
If the response streams a large file, the Writable stream applies highWaterMark. When the client reads slowly, the 'drain' event pauses the producer to prevent memory blowup.
Event loop là nền tảng: mọi thứ chạy trên một thread duy nhất và I/O không bao giờ block. Đó là lý do Node.js có thể xử lý hàng nghìn kết nối đồng thời — mỗi request dùng các pattern (middleware, observer, backpressure) thay vì sinh thêm thread.