~3 دقیقه مطالعه • بروزرسانی ۵ دی ۱۴۰۴
1. AsyncLocalStorage
کلاس AsyncLocalStorage یک فضای ذخیرهسازی ایجاد میکند که در طول عملیات ناهمگام پایدار باقی میماند. این کلاس برای ساخت loggerها، مدیریت sessionها یا انتقال داده در زنجیرههای Promise بسیار مفید است.
مثال ساده:
const { AsyncLocalStorage } = require('node:async_hooks');
const asyncLocalStorage = new AsyncLocalStorage();
function logWithId(msg) {
const id = asyncLocalStorage.getStore();
console.log(`${id !== undefined ? id : '-'}:`, msg);
}
هر نمونهٔ AsyncLocalStorage مستقل است و میتواند بدون تداخل با نمونههای دیگر استفاده شود.
2. متدهای مهم AsyncLocalStorage
run(store, callback): اجرای یک تابع در کانتکست مشخصgetStore(): دریافت مقدار ذخیرهشده در کانتکست جاریenterWith(store): ورود به کانتکست مشخص برای اجرای همگامexit(callback): خروج از کانتکست و اجرای تابع خارج از آنdisable(): غیرفعالسازی نمونه برای آزادسازی حافظهbind(fn)وsnapshot(): اتصال یا گرفتن snapshot از کانتکست جاری
3. AsyncResource
کلاس AsyncResource برای توسعهدهندگان طراحی شده تا بتوانند منابع ناهمگام سفارشی بسازند و چرخهٔ عمر آنها را مدیریت کنند.
ویژگیها:
runInAsyncScope(fn, thisArg, ...args): اجرای تابع در کانتکست منبع ناهمگامemitDestroy(): فراخوانی hookهای تخریبasyncId(): شناسهٔ یکتا برای منبعtriggerAsyncId(): شناسهٔ منبعی که این منبع را ایجاد کرده
مثال:
class DBQuery extends AsyncResource {
constructor(db) {
super('DBQuery');
this.db = db;
}
getInfo(query, callback) {
this.db.get(query, (err, data) => {
this.runInAsyncScope(callback, null, err, data);
});
}
close() {
this.db = null;
this.emitDestroy();
}
}
4. استفاده در Worker Pool
با استفاده از AsyncResource میتوان یک Worker Pool ساخت که وظایف را بهدرستی ردیابی کند و کانتکستها را حفظ نماید.
class WorkerPoolTaskInfo extends AsyncResource {
constructor(callback) {
super('WorkerPoolTaskInfo');
this.callback = callback;
}
done(err, result) {
this.runInAsyncScope(this.callback, null, err, result);
this.emitDestroy();
}
}
این الگو برای مدیریت منابعی مانند پایگاه داده یا thread pool بسیار کاربردی است.
5. ادغام با EventEmitter
EventEmitterها ممکن است در کانتکست متفاوتی اجرا شوند. با استفاده از AsyncResource.bind() میتوان اطمینان حاصل کرد که listenerها در کانتکست صحیح اجرا میشوند.
req.on('close', AsyncResource.bind(() => {
// Execution context is bound correctly
}));
نتیجهگیری
ماژول async_hooks در Node.js ابزار قدرتمندی برای مدیریت کانتکستهای ناهمگام است. با استفاده از AsyncLocalStorage و AsyncResource میتوان دادهها را در طول چرخهٔ عمر عملیات ناهمگام حفظ کرد، منابع سفارشی ساخت و از بروز مشکلاتی مانند context loss جلوگیری نمود. این قابلیتها برای ساخت برنامههای وب مقیاسپذیر و پایدار حیاتی هستند.
نوشته و پژوهش شده توسط دکتر شاهین صیامی