async_hooks là gì?
async_hooks là một module cốt lõi trong Node.js ra mắt từ phiên bản 8. Nó cho phép bạn theo dõi vòng đời của các tác vụ bất đồng bộ (Promises, Timer, I/O…) thông qua các hook như init, before, after và destroy. Với công cụ này, bạn có thể hiểu rõ cách callback, promise và sự kiện hoạt động trong event loop.
Cách hoạt động của async_hooks
Khi một tác vụ bất đồng bộ được tạo, nó được gán một asyncId duy nhất và liên kết với triggerAsyncId của tác vụ cha. Các hook chính bao gồm:
init(asyncId, type, triggerAsyncId, resource): được gọi khi một tác vụ async khởi tạo.typecho biết loại tác vụ (Promise, Timeout, TCPWrap…).before(asyncId): chạy ngay trước khi callback của tác vụ thực thi.after(asyncId): chạy sau khi callback hoàn thành.destroy(asyncId): gọi khi tài nguyên async được giải phóng khỏi bộ nhớ.
Ví dụ sử dụng async_hooks
const async_hooks = require('async_hooks');
const fs = require('fs');
const log = msg => fs.writeSync(1, `${msg}\n`);
const hooks = async_hooks.createHook({
init(asyncId, type, triggerAsyncId) {
log(`Init: asyncId=${asyncId}, type=${type}, triggerAsyncId=${triggerAsyncId}`);
},
before(asyncId) {
log(`Before: asyncId=${asyncId}`);
},
after(asyncId) {
log(`After: asyncId=${asyncId}`);
},
destroy(asyncId) {
log(`Destroy: asyncId=${asyncId}`);
}
});
hooks.enable();
setTimeout(() => {
log('Hello from setTimeout');
}, 100); Giải thích:
- Mỗi lần
setTimeoutđược tạo sẽ gọi hookinit. - Ngay trước khi callback của
setTimeoutchạy thì hookbefoređược kích hoạt. - Sau khi callback hoàn thành, hook
aftersẽ được gọi. - Khi tài nguyên timeout bị giải phóng, hook
destroychạy.
Ứng dụng thực tế
- Debug & monitoring hiệu suất: theo dõi các tác vụ bất đồng bộ để phát hiện rò rỉ hoặc tối ưu thời gian thực thi.
- Context Tracking: xây dựng
AsyncLocalStorageđể lưu trữ dữ liệu theo ngữ cảnh của từng request, hữu ích cho các ứng dụng web. - Logging & profiling: ghi log luồng thực thi bất đồng bộ nhằm hiểu rõ cấu trúc ứng dụng.
Kết luận
Module async_hooks là công cụ mạnh mẽ giúp bạn quan sát và phân tích luồng bất đồng bộ trong Node.js. Khi kết hợp với các kỹ thuật logging, bạn có thể cải thiện hiệu năng, phát hiện lỗi và xây dựng các dịch vụ phức tạp một cách hiệu quả.