النود جي إس معروف بشكل واسع ببنائه غير المثبط، الهيكل المتزامن، مما يجعله خيارًا محبوبًا للتطبيقات التي تتطلب مرونة عالية الأداء. ومع ذلك، يمكن أن يكون التعامل مع التوازي بكفاءة في النود جي إس تحديًا، خاصة عندما تصبح التطبيقات معقدة. في هذا المقال، سنستعرض كيفية إدارة التوازي في النود جي إس باستخدام async
و await
ونتحدث عن كيفية تحسين أداء هذه الأدوات.
لماذا التوازي مهم في النود جي إس
التوازي يتيح تشغيل مهام متعددة في نفس الوقت دون عرقلة بعضها البعض. في بيئة متزامنة أو مثبطة، يتم تنفيذ الكود بشكل متتابع، مما يعني أن كل مهمة يجب أن تنتهي قبل أن تبدأ المهمة التالية. النود جي إس، ومع ذلك، مصمم لمعالجة العمليات غير المتزامنة، مما يسمح للخادم إدارة طلبات متعددة دون الانتظار حتى تنتهي الطلبات السابقة.
كمستviron غير متعدد الخيوط، يعتمد على الأحداث، يمكن للنود جي إس التعامل مع عمليات متعددة متزامنة من خلال حلقة الأحداث. هذا الهيكل غير المثبط هو ركيزة لكل شركة تطوير النود جي إس تسعى لبناء تطبيقات تتعامل بكفاءة مع مهام إدخال\إخراج ثقيلة، مثل استعلامات قاعدة البيانات، استدعاءات الشبكة، أو عمليات الملفات.
فهمAsync وawait في النود جي إس
أدى إدخال async
و await
في ES2017 إلى تسهيل العمل مع الكود غير المتزامن في JavaScript. تتيح هذه الكلمات الرئيسية للمطورين كتابة كود غير متزامن يبدو ويتصرف مثل الكود المتزامن، مما يحسن من قابلية القراءة ويقلل من فرصة الوقوع في مشاكل “الجحيم الخاص بالاستدعاءات”.
- Async: يضمن إعلان وظيفة كـ
async
عودتها تلقائيًا بـPromise
، مما يعني أنه يمكنك استخدامawait
داخلها. - Await: يوقف تنفيذ وظيفة غير متزامنة حتى يتم حل الـ
Promise
أو رفضه. هذا يسمح بالتعامل مع الكود غير المتزامن بطريقة خطية، خطوة بخطوة.
لأي خدمات تطوير Node.js تسعى لتبسيط كودها، يوفر async
و await
بديلاً أنظف عن تسلسل الـ Promise
التقليدي.
الاستخدام الأساسي لـ Async و Await
لنبدأ بمثال أساسي لفهم كيفية عمل async
و await
في تطبيق Node.js.
في المثال أدناه، يقوم await
بإيقاف التنفيذ داخل وظيفة fetchData
حتى تكتمل عمليات fetch
و data.json()
. هذه الصياغة البسيطة تحافظ على قراءة الكود وسهولة صيانته.
async function fetchData() {
try {
const data = await fetch('https://api.example.com/data');
const result = await data.json();
console.log(result);
} catch (error) {
console.error('Error fetching data:', error);
}
}
fetchData();
معالجة عدة وعود بشكل متزامن
أحد الفوائد الرئيسية لبرمجة التعاملات الآسин크 (async) هو القدرة على التعامل مع مهام آسية متعددة بشكل متوازي. بدلاً من الانتظار حتى يتم إكمال كل مهمة بشكل متتابع، يتيح لك Promise.all()
تنفيذها بشكل متزامن، مما يمكن أن يقلل بشكل كبير من زمن التنفيذ.
مثال: استخدام Promise.all()
في هذا المثال، يبدأ كلاً من المكالمات API بشكل متزامن، ويانتظر الدالة حتى يتم إكمالهما. هذه التقنية مهمة جدًا لتطوير خدمات Node.js التي تتعامل مع مكالمات API متعددة أو استعلامات قاعدة بيانات متعددة، حيث تقلل من زمن الإنتظار لأعمال الإدخال والإخراج (I/O operations)، وبالتالي تحسين الأداء.
async function loadData() {
try {
const [users, posts] = await Promise.all([
fetch('https://api.example.com/users'),
fetch('https://api.example.com/posts')
]);
console.log('Users:', await users.json());
console.log('Posts:', await posts.json());
} catch (error) {
console.error('Error loading data:', error);
}
}
loadData();
التنفيذ المتتابع مقابل التنفيذ المتوازي في Node.js
فهم متى يجب تنفيذ المهام بشكل متتابع أو متوازي أمر حاسم لبناء تطبيقات كفؤة.
التنفيذ المتتابع
التنفيذ المتتابع مناسب للمهام التي تعتمد على بعضها البعض. على سبيل المثال، إذا كانت إحدى استعلامات قاعدة البيانات تعتمد على نتائج أخرى، يجب تنفيذها بشكل متتابع.
async function sequentialTasks() {
const firstResult = await taskOne();
const secondResult = await taskTwo(firstResult);
return secondResult;
}
التنفيذ المتوازي
التنفيذ المتوازي هو الأفضل للمهام المستقلة. استخدام Promise.all()
يسمح للمهام بالتنفيذ بشكل متوازي، مما يزيد من الكفاءة.
async function parallelTasks() {
const [result1, result2] = await Promise.all([
taskOne(),
taskTwo()
]);
return [result1, result2];
}
لأي شركة تطوير Node.js تركز على الأداء، تحديد متى يجب استخدام التنفيذ المتتابع أو المتوازي يمكن أن يحدث فرقًا كبيرًا في سرعة التطبيق واستخدام الموارد.
إدارة الأخطاء في Async وAwait
إدارة الأخطاء هي جزء أساسي من العمل مع الدوال غير المتزامنة. يمكن إدارة الأخطاء باستخدام bloacks try...catch
، مما يجعل التعامل مع الأخطاء أمرًا بسيطًا ويقلل من فرص حدوث استثناءات غير محتشفة ت打扰 التطبيق.
مثال: استخدام Try…Catch مع Async وAwait
استخدام try...catch
في الدوال غير المتزامنة يساعد مطورو Node.js على إدارة الأخطاء بفعالية، مما يضمن إلتقاط问题和 التعامل معها بلياقة.
async function getData() {
try {
const response = await fetch('https://api.example.com/data');
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error('An error occurred:', error);
}
}
getData();
إدارة المهام الطويلة الأمد مع Async وAwait
للمطورين الذين يعملون على خدمات Node.js، إدارة المهام الطويلة الأمد في الخلفية دون إغلاق السلك الرئيسي أمر حاسم. توفر Node.js مهام خلفية و تنفيذ متأخر باستخدام setTimeout()
أو مكتبات خارجية مثل bull
لإدارة الأ队伍建设، مما يضمن أن المهام المكثفة لا تبطئ التطبيق.
مثال: تأجيل التنفيذ في الدوال غير المتزامنة
المهام الطويلة الأمد مفيدة بشكل خاص للمطورين الذين يعملون على تطوير Node.js الذين يديرون تطبيقات مع عملياتbackend معقدة، مما يضمن تشغيل المهام الثقيلة بكفاءة في الخلفية.نصائح لتحسين التزامن مع Async وAwait
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function delayedTask() {
console.log('Starting task...');
await delay(3000); // Pauses execution for 3 seconds
console.log('Task completed');
}
delayedTask();
- استخدام Promise.allSettled(): لعدة مهام حيث لا يجب أن يؤثر فشل مهمة واحدة على الأخرى،
Promise.allSettled()
مفيد. يضمن هذا Method أن جميع الوعود تتحقق قبل المضي قدمًا. - تحديد الطلبات المتزامنة: يمكن أن تتسبب الطلبات المتزامنة الكثيرة في تحميل كبير على الخوادم. تساعد مكتبات مثل
p-limit
في تحديد عدد الطلبات المتزامنة، مما يمنع تدهور الأداء. - الابتعاد عن الدعوات المتكررة للـ async: يمكن أن يؤدي استخدام الدعوات المتكررة للـ async إلى تعقيد مشابه لـ callback hell. بدلاً من ذلك، قم بتجزئة الدوال إلى أجزاء صغيرة قابلة لإعادة الاستخدام.
- استخدام مكتبات الـ async للتحكم في الدفع: تدير مكتبات مثل
bull
وkue
المهام في الخلفية، مما يسهل التعامل مع العمليات الطويلة الأمد أو المتكررة في خدمات تطوير Node.js دون إعاقة السطر الرئيسي.
الخاتمة
إدارة التزامن بفعالية في Node.js باستخدام async
و await
هي طريقة قوية لبناء تطبيقات سريعة وقابلة للتمديد. من خلال فهم متى تستخدم التنفيذ التسلسلي مقابل التنفيذ المتوازي، وتطبيق إدارة الأخطاء، وتحسين المهام الطويلة الأمد، يمكن لشركات تطوير Node.js التأكد من الأداء العالي حتى تحت الأحمال الكبيرة.
بالنسبة لتطوير Node.js التركيز على تحسين الأداء، تساعد هذه التقنيات في التعامل مع معالجة البيانات، ودعوات API، والمهام Backend المعقدة دون المساس بتجربة المستخدم. تبني برمجة Async في Node.js هو المفتاح لإنشاء تطبيقات فعالة، موثوقة يمكنها التعامل مع التزامن بسلاسة.
Source:
https://dzone.com/articles/handling-concurrency-in-nodejs-with-async-and-await