از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
استفاده از قلابهای Async برای رسیدگی به زمینه درخواست در Node.jsAsync Hookها یک ماژول اصلی در Node.js هستند که یک API برای ردیابی طول عمر منابع ناهمزمان در برنامه Node ارائه میدهند. یک منبع ناهمزمان را می توان به عنوان یک شی در نظر گرفت که دارای یک تماس مرتبط است. به عنوان مثال می توان به موارد زیر اشاره کرد، اما به آنها محدود نمی شود: Promises، Timeouts، TCPWrap، UDP…
سرفصلهای مطلب
معرفی
قلاب های همگام یک ماژول اصلی در Node.js است که یک API برای ردیابی طول عمر منابع ناهمزمان در یک برنامه Node ارائه می دهد. یک منبع ناهمزمان را می توان به عنوان یک شی در نظر گرفت که دارای یک تماس مرتبط است.
نمونهها عبارتند از، اما محدود به این موارد: Promises، Timeouts، TCPWrap، UDP و غیره. فهرست کامل منابع ناهمزمان که میتوانیم با استفاده از این API ردیابی کنیم اینجا.
ویژگی Async Hooks در سال 2017 در Node.js نسخه 8 معرفی شد و هنوز آزمایشی است. این بدان معناست که ممکن است همچنان تغییرات ناسازگار با عقب در نسخههای بعدی API ایجاد شود. همانطور که گفته شد، در حال حاضر برای تولید مناسب نیست.
در این مقاله، نگاهی عمیقتر به قلابهای Async خواهیم داشت – چه هستند، چرا مهم هستند، کجا میتوانیم از آنها استفاده کنیم و چگونه میتوانیم از آنها برای یک مورد خاص استفاده کنیم، یعنی درخواست مدیریت زمینه در یک Node. js و اپلیکیشن Express.
Async Hooks چیست؟
همانطور که قبلاً گفته شد، کلاس Async Hooks یک ماژول اصلی Node.js است که یک API برای ردیابی منابع ناهمزمان در برنامه Node.js شما ارائه می دهد. این همچنین شامل ردیابی منابع ایجاد شده توسط ماژول های Node بومی مانند fs
و net
.
در طول عمر یک منبع async، 4 رویداد وجود دارد که فعال می شوند و ما می توانیم با Async Hooks آنها را ردیابی کنیم. این شامل:
init
– در هنگام ساخت منبع async فراخوانی شدbefore
– قبل از فراخوانی تماس مجدد منبع فراخوانی شده استafter
– پس از فراخوانی تماس مجدد منبع فراخوانی می شودdestroy
– پس از از بین رفتن منبع async فراخوانی می شودpromiseResolve
– زمانی که تماس گرفتresolve()
تابع یک Promise فراخوانی می شود.
در زیر یک قطعه خلاصه از Async Hooks API از نمای کلی در مستندات Node.js:
const async_hooks = require('async_hooks');
const exec_id = async_hooks.executionAsyncId();
const trigger_id = async_hooks.triggerAsyncId();
const asyncHook = async_hooks.createHook({
init: function (asyncId, type, triggerAsyncId, resource) { },
before: function (asyncId) { },
after: function (asyncId) { },
destroy: function (asyncId) { },
promiseResolve: function (asyncId) { }
});
asyncHook.enable();
asyncHook.disable();
این executionAsyncId()
متد یک شناسه از زمینه اجرای فعلی را برمی گرداند.
این triggerAsyncId()
متد، شناسه منبع والد را برمیگرداند که اجرای منبع async را آغاز کرده است.
این createHook()
متد یک همگام ایجاد می کند hook به عنوان مثال، در نظر گرفتن رویدادهای فوق به عنوان تماس های اختیاری.
برای فعال کردن ردیابی منابع خود، ما با آن تماس می گیریم enable()
روش همگام ما hook نمونه ای که با آن ایجاد می کنیم createHook()
روش.
همچنین می توانیم با تماس با شماره ردیابی را غیرفعال کنیم disable()
تابع.
پس از دیدن آنچه که Async Hooks API مستلزم آن است، بیایید بررسی کنیم که چرا باید از آن استفاده کنیم.
چه زمانی از Async Hooks استفاده کنیم
افزودن قلابهای Async به API اصلی از مزایا و موارد استفاده زیادی بهره برده است. برخی از آنها عبارتند از:
- اشکال زدایی بهتر – با استفاده از قلابهای Async، میتوانیم ردپای پشتهای از توابع async را بهبود بخشیده و غنی کنیم.
- قابلیتهای ردیابی قدرتمند، بهویژه زمانی که با Node’s Performance API ترکیب شوند. همچنین، از آنجایی که Async Hooks API بومی است، حداقل سربار عملکرد وجود دارد.
- مدیریت زمینه درخواست وب – برای گرفتن اطلاعات یک درخواست در طول عمر آن درخواست، بدون ارسال شی درخواست در همه جا. با استفاده از قلابهای Async، این کار را میتوان در هر جایی از کد انجام داد و میتواند به ویژه هنگام ردیابی رفتار کاربران در سرور مفید باشد.
در این مقاله، روش رسیدگی به ردیابی ID درخواست با استفاده از Async Hooks در یک برنامه Express را بررسی خواهیم کرد.
استفاده از قلاب های Async برای رسیدگی به زمینه درخواست
در این بخش، نشان خواهیم داد که چگونه میتوانیم از Async Hooks برای انجام ردیابی ID درخواست ساده در یک برنامه Node.js استفاده کنیم.
راه اندازی Request Context Handlers
ما با ایجاد یک دایرکتوری شروع می کنیم که فایل های برنامه ما در آن قرار می گیرند، سپس وارد آن می شویم:
mkdir async_hooks && cd async_hooks
بعد، ما باید برنامه Node.js خود را در این دایرکتوری با مقداردهی اولیه کنیم npm
و تنظیمات پیش فرض:
npm init -y
این باعث ایجاد یک package.json
فایل در root از دایرکتوری
بعد، ما باید نصب کنیم Express
و uuid
بسته ها به عنوان وابستگی ما استفاده خواهیم کرد uuid
بسته ای برای ایجاد یک شناسه منحصر به فرد برای هر درخواست ورودی.
در نهایت، ما نصب می کنیم esm
ماژول بنابراین نسخه های Node.js پایین تر از v14 می توانند این مثال را اجرا کنند:
npm install express uuid esm --save
بعد، یک را ایجاد کنید hooks.js
فایل در root از دایرکتوری:
touch hooks.js
این فایل حاوی کدی است که با آن تعامل دارد async_hooks
مدول. این دو عملکرد را صادر می کند:
- یکی که یک قلاب Async را برای درخواست HTTP فعال می کند، شناسه درخواست داده شده آن و هر داده درخواستی را که می خواهیم حفظ کنیم، پیگیری می کند.
- دیگری داده های درخواست مدیریت شده توسط را برمی گرداند hook با توجه به شناسه هوک Async آن.
بیایید آن را در کد قرار دهیم:
require = require('esm')(module);
const asyncHooks = require('async_hooks');
const { v4 } = require('uuid');
const store = new Map();
const asyncHook = asyncHooks.createHook({
init: (asyncId, _, triggerAsyncId) => {
if (store.has(triggerAsyncId)) {
store.set(asyncId, store.get(triggerAsyncId))
}
},
destroy: (asyncId) => {
if (store.has(asyncId)) {
store.delete(asyncId);
}
}
});
asyncHook.enable();
const createRequestContext = (data, requestId = v4()) => {
const requestInfo = { requestId, data };
store.set(asyncHooks.executionAsyncId(), requestInfo);
return requestInfo;
};
const getRequestContext = () => {
return store.get(asyncHooks.executionAsyncId());
};
module.exports = { createRequestContext, getRequestContext };
در این قطعه کد، ابتدا نیاز داریم esm
ماژول برای ارائه سازگاری به عقب برای نسخههای Node که پشتیبانی بومی برای صادرات ماژول آزمایشی ندارند. این ویژگی به صورت داخلی مورد استفاده قرار می گیرد uuid
مدول.
بعد، ما همچنین به هر دو مورد نیاز داریم async_hooks
و uuid
ماژول ها از uuid
ماژول را از بین می بریم v4
تابعی که بعداً برای تولید UUID های نسخه 4 از آن استفاده خواهیم کرد.
در مرحله بعد، ما یک فروشگاه ایجاد می کنیم که هر منبع ناهمگام را با زمینه درخواست خود ترسیم می کند. برای این کار از یک نقشه جاوا اسکریپت ساده استفاده می کنیم.
بعد، ما را صدا می کنیم createHook()
روش از async_hooks
ماژول و پیاده سازی init()
و destroy()
پاسخ به تماس ها در اجرای ما init()
پاسخ به تماس، بررسی می کنیم که آیا triggerAsyncId
در فروشگاه حضور دارد
اگر وجود داشته باشد، یک نقشه برداری از آن ایجاد می کنیم asyncId
به داده های درخواست ذخیره شده در زیر triggerAsyncId
. این در واقع تضمین می کند که ما همان شی درخواست را برای منابع ناهمزمان فرزند ذخیره می کنیم.
این destroy()
پاسخ به تماس بررسی میکند که آیا فروشگاه دارای آن است یا خیر asyncId
منبع، و در صورت صحت آن را حذف می کند.
برای استفاده از ما hook، با فراخوانی آن را فعال می کنیم enable()
روش از asyncHook
نمونه ای که ما ایجاد کرده ایم
بعد، ما 2 تابع ایجاد می کنیم – createRequestContext()
و getRequestContext
که به ترتیب برای ایجاد و دریافت زمینه درخواست خود استفاده می کنیم.
این createRequestContext()
تابع داده های درخواست و یک شناسه منحصر به فرد را به عنوان آرگومان دریافت می کند. سپس یک را ایجاد می کند requestInfo
شیء از هر دو آرگومان و تلاش برای به روز رسانی فروشگاه با شناسه async متن اجرای فعلی به عنوان کلید، و requestInfo
به عنوان ارزش
این getRequestContext()
تابع، روی از سوی دیگر، بررسی می کند که آیا فروشگاه دارای شناسه ای مطابق با شناسه زمینه اجرای فعلی است یا خیر.
ما بالاخره export هر دو تابع با استفاده از module.exports()
نحو.
ما با موفقیت عملکرد مدیریت زمینه درخواست خود را تنظیم کردیم. بیایید راه اندازی خود را ادامه دهیم Express
سروری که درخواست ها را دریافت می کند.
راه اندازی سرور اکسپرس
پس از تنظیم زمینه خود، اکنون به ایجاد خود ادامه می دهیم Express
سرور تا بتوانیم درخواست های HTTP را دریافت کنیم. برای انجام این کار، یک را ایجاد کنید server.js
فایل در root دایرکتوری به شرح زیر
touch server.js
سرور ما یک درخواست HTTP را می پذیرد روی پورت 3000. یک قلاب Async ایجاد می کند تا هر درخواست را با فراخوانی ردیابی کند createRequestContext()
در یک میان افزار تابع – تابعی که به اشیاء درخواست و پاسخ HTTP دسترسی دارد. سپس سرور یک پاسخ JSON را با داده های گرفته شده توسط Async Hook ارسال می کند.
درون server.js
فایل، کد زیر را وارد کنید:
const express = require('express');
const ah = require('./hooks');
const app = express();
const port = 3000;
app.use((request, response, next) => {
const data = { headers: request.headers };
ah.createRequestContext(data);
next();
});
const requestHandler = (request, response, next) => {
const reqContext = ah.getRequestContext();
response.json(reqContext);
next()
};
app.get('/', requestHandler)
app.listen(port, (err) => {
if (err) {
return console.error(err);
}
console.log(`server is listening روی ${port}`);
});
در این قطعه کد، ما نیاز داریم express
و ما hooks
ماژول ها به عنوان وابستگی سپس یک را ایجاد می کنیم Express
برنامه با تماس با express()
تابع.
در مرحله بعد، ما یک میان افزار راه اندازی می کنیم که هدرهای درخواست را از ساختار خارج می کند و آنها را در متغیری به نام ذخیره می کند data
. سپس آن را فرا می خواند createRequestContext()
عبور تابع data
به عنوان یک استدلال این تضمین می کند که هدرهای درخواست در طول چرخه عمر درخواست با قلاب Async حفظ می شوند.
در نهایت، ما به next()
برای رفتن به میان افزار بعدی در خط لوله میان افزار ما یا فراخوانی کنترل کننده مسیر بعدی.
بعد از میان افزار خود، ما آن را می نویسیم requestHandler()
تابعی که a GET
درخواست روی سرور root دامنه. متوجه خواهید شد که در این تابع، ما میتوانیم از طریق به متن درخواست خود دسترسی داشته باشیم getRequestContext()
تابع. این تابع یک شی را برمی گرداند که نشان دهنده سرصفحه های درخواست و شناسه درخواست تولید و ذخیره شده در زمینه درخواست است.
سپس یک نقطه پایانی ساده ایجاد می کنیم و کنترل کننده درخواست خود را به عنوان یک پاسخ به تماس متصل می کنیم.
در نهایت، ما سرور خود را به اتصالات گوش می دهیم روی پورت 3000 با تماس با listen()
روش نمونه برنامه ما
قبل از اجرای کد، آن را باز کنید package.json
فایل در root دایرکتوری و جایگزین کنید test
بخش اسکریپت با این:
"start": "node server.js"
با انجام این کار، می توانیم برنامه خود را با دستور زیر اجرا کنیم:
npm start
شما باید یک پاسخ دریافت کنید روی شما terminal نشان می دهد که برنامه در حال اجرا است روی پورت 3000، مطابق شکل:
> (email protected) start /Users/allanmogusu/rasanegar/async-hooks-demo
> node server.js
(node:88410) ExperimentalWarning: Conditional exports is an experimental feature. This feature could change at any time
server is listening روی 3000
با اجرای برنامه ما، یک برنامه جداگانه باز کنید terminal نمونه و موارد زیر را اجرا کنید curl
دستور برای آزمایش مسیر پیش فرض ما:
curl http://localhost:3000
این curl
فرمان a GET
درخواست مسیر پیش فرض ما. شما باید پاسخی مشابه این دریافت کنید:
$ curl http://localhost:3000
{"requestId":"3aad88a6-07bb-41e0-ab5a-fa9d5c0269a7","data":{"headers":{"host":"localhost:3000","user-agent":"curl/7.64.1","accept":"*/*"}}}%
توجه داشته باشید که تولید شده است requestId
و سرصفحه های درخواست ما برگردانده می شوند. تکرار دستور باید یک شناسه درخواست جدید ایجاد کند زیرا ما یک درخواست جدید خواهیم داشت:
$ curl http://localhost:3000
{"requestId":"38da84792-e782-47dc-92b4-691f4285b172","data":{"headers":{"host":"localhost:3000","user-agent":"curl/7.64.1","accept":"*/*"}}}%
پاسخ شامل شناسهای است که ما برای درخواست ایجاد کردهایم و هدرهایی که در تابع میانافزار گرفتهایم. با Async Hooks میتوانیم به راحتی دادهها را برای همان درخواست از یک میانافزار به میانافزار دیگر منتقل کنیم.
نتیجه
Async Hooks یک API برای ردیابی طول عمر منابع ناهمزمان در یک برنامه Node.js فراهم می کند.
در این مقاله، ما به طور خلاصه به Async Hooks API، عملکردی که ارائه میکند و اینکه چگونه میتوانیم از آن استفاده کنیم، نگاه کردهایم. ما به طور خاص یک مثال اساسی از روش استفاده از قلاب های Async برای انجام مدیریت و ردیابی متن درخواست وب به طور موثر و تمیز پوشش داده ایم.
با این حال، از زمان Node.js نسخه 14، Async Hooks API با فضای ذخیرهسازی محلی ناهمگام ارائه میشود، API که مدیریت زمینه درخواست را در Node.js آسانتر میکند. می توانید در مورد آن بیشتر بخوانید اینجا. همچنین کد این آموزش قابل دسترسی است اینجا.
(برچسبها برای ترجمه)# جاوا اسکریپت
منتشر شده در 1403-01-20 11:06:03