قوائم انتظار المهام في JavaScript (Node.js): دليل شامل

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

العمل مع قوائم المهام في JavaScript (Node.js)



في تطبيقات الويب الحديثة والهندسة المعمارية للخدمات المصغرة، غالباً ما تنشأ الحاجة لتنفيذ مهام خلفية لا ينبغي أن تعيق سير التنفيذ الرئيسي. قوائم المهام هي أداة قوية تساعد في إدارة العمليات غير المتزامنة، مما يضمن الموثوقية وقابلية التوسع وتحمل الأخطاء. في هذه المقالة، سنشرح بالتفصيل كيفية العمل مع قوائم المهام في بيئة Node.js، وسنستعرض المكتبات الرئيسية ونكتب أمثلة عملية للكود.



ما هي قائمة المهام ولماذا نحتاجها؟



قائمة المهام (Task Queue) هي بنية بيانات تعمل وفق مبدأ FIFO (First In, First Out - "من يدخل أولاً يخرج أولاً"). يتم وضع المهام في القائمة ومعالجتها بواسطة العمال (worker) بترتيب وصولها. تشمل السيناريوهات الرئيسية للاستخدام:



  • إرسال إشعارات البريد الإلكتروني - لا حاجة لإجبار المستخدم على الانتظار حتى يتم إرسال الرسالة.
  • إنشاء التقارير أو PDF - عمليات تستهلك موارد كبيرة، ومن الأفضل تنفيذها بشكل غير متزامن.
  • معالجة الصور المرفوعة - تغيير الحجم، الضغط، إضافة العلامات المائية.
  • التكامل مع واجهات برمجة التطبيقات الخارجية - تنفيذ الطلبات مع تحديد التردد (rate limiting).
  • المهام المجدولة (cron) - التنظيف الدوري لقاعدة البيانات أو تحديث الذاكرة المؤقتة.


استخدام القوائم يسمح بتخفيف الحمل عن الخادم الرئيسي، وزيادة تحمل الأخطاء (إذا تعطل عامل، سيتم نقل المهمة إلى آخر)، وضمان تنفيذ المهمة حتى في حالات الأعطال المؤقتة.



قائمة بسيطة في الذاكرة على Node.js



لنبدأ بتنفيذ قائمة بسيطة بدون اعتماديات خارجية. هذا النهج مناسب للنماذج الأولية أو المشاريع الصغيرة جداً، لكنه لا يُوصى به للإنتاج بسبب عدم وجود استمرارية.



class SimpleQueue {    constructor() {        this.queue = [];        this.processing = false;    }

enqueue(task) { this.queue.push(task); this.processNext(); }

async processNext() { if (this.processing || this.queue.length === 0) return; this.processing = true; const task = this.queue.shift(); try { await task(); } catch (err) { console.error('خطأ في تنفيذ المهمة:', err); } finally { this.processing = false; this.processNext(); } }}

// مثال على الاستخدامconst queue = new SimpleQueue();

queue.enqueue(async () => { console.log('المهمة 1: إرسال البريد الإلكتروني');});

queue.enqueue(async () => { console.log('المهمة 2: إنشاء التقرير');});

console.log('تمت إضافة المهام إلى القائمة');


يوضح هذا الكود الآلية الأساسية: يتم تنفيذ المهام بشكل تسلسلي، واحدة تلو الأخرى. ومع ذلك، عند إعادة تشغيل الخادم، سيتم فقدان جميع المهام غير المعالجة.



Bull — قائمة مهام احترافية على Redis



للمشاريع الجادة في Node.js، المكتبة الفعلية المعيارية هي Bull. تستخدم Redis كخلفية، مما يضمن الاستمرارية، ودعم الأولويات، وإعادة المحاولة، والمهام المؤجلة.



التثبيت:

npm install bull


مثال على منتج ومستهلك بسيط:



const Queue = require('bull');

// إنشاء قائمة باسم 'email-queue'const emailQueue = new Queue('email-queue', { redis: { host: 'localhost', port: 6379 }});

// وظيفة العامل: معالجة المهامemailQueue.process(async (job) => { const { to, subject, body } = job.data; console.log(`إرسال بريد إلكتروني إلى ${to}: ${subject}`); // هنا سيكون الكود الفعلي لإرسال البريد الإلكتروني await new Promise(resolve => setTimeout(resolve, 1000)); return { success: true };});

// إضافة المهام

المدونات

توصيات الكتب