قوائم المهام في TypeScript: إنشاء وتحسين المعالجة

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

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

ابدأ الدورة
```html

العمل مع قوائم المهام في TypeScript: دليل شامل

في تطوير الويب الحديث وتطبيقات الخادم، غالباً ما تنشأ الحاجة لتنفيذ المهام بشكل غير متزامن، في الخلفية، أو مع تحديد التوازي. قوائم المهام (task queues) هي نمط قوي يسمح بتنظيم تنفيذ العمليات بشكل متوقع وفعال. في هذه المقالة، سنشرح بالتفصيل كيفية إنشاء واستخدام قوائم المهام في TypeScript، بدءاً من التطبيقات البسيطة وصولاً إلى التقنيات المتقدمة مع الأولويات ومعالجة الأخطاء.



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

قائمة المهام هي بنية بيانات تعمل وفق مبدأ FIFO (First In, First Out). تُضاف المهام إلى نهاية القائمة، وتُستخرج من البداية. في سياق TypeScript و Node.js، تُستخدم القوائم من أجل:

  • تحديد التوازي — التحكم في عدد العمليات المنفذة في وقت واحد (مثل طلبات API ذات الحدود).
  • المعالجة غير المتزامنة — تنفيذ المهام الثقيلة في الخلفية دون حظر الخيط الرئيسي.
  • المحاولات المتكررة — إعادة التشغيل التلقائي للمهام الفاشلة مع تأخير.
  • إدارة الترتيب — ضمان التنفيذ المتسلسل للعمليات التابعة.

يضيف TypeScript كتابة صارمة، مما يجعل كود القوائم أكثر موثوقية وقابلية للتنبؤ.



تطبيق أساسي لقائمة المهام في TypeScript

لنبدأ بإنشاء قائمة بسيطة ولكنها مكتوبة بالكامل. ستقبل المهام (دوال تُرجع Promise) وتنفذها بشكل متسلسل.

// تعريف نوع المهمةtype Task<T> = () => Promise<T>;

// فئة القائمةclass TaskQueue<T> { private queue: Task<T>[] = []; private isProcessing: boolean = false;

// إضافة مهمة إلى القائمة enqueue(task: Task<T>): void { this.queue.push(task); this.process(); }

// بدء المعالجة private async process(): Promise<void> { if (this.isProcessing) return; this.isProcessing = true;

while (this.queue.length > 0) { const task = this.queue.shift()!; try { const result = await task(); console.log('تم تنفيذ المهمة:', result); } catch (error) { console.error('خطأ في تنفيذ المهمة:', error); } }

this.isProcessing = false; }}

// مثال على الاستخدامconst queue = new TaskQueue<string>();queue.enqueue(async () => { await new Promise(resolve => setTimeout(resolve, 1000)); return 'المهمة الأولى';});queue.enqueue(async () => 'المهمة الثانية (سريعة)');

يضمن هذا التطبيق التنفيذ المتسلسل والبدء التلقائي للمعالجة عند إضافة مهمة جديدة. ومع ذلك، فهو لا يدعم التوازي والأولويات.



قائمة مع تحديد التوازي

غالباً ما يكون مطلوباً تنفيذ عدة مهام في وقت واحد، ولكن دون تجاوز حد معين (مثل 5 طلبات متوازية). سنضيف المعامل concurrency.

class ParallelTaskQueue<T> {    private queue: Task<T>[] = [];    private activeCount: number = 0;    private readonly concurrency: number;

constructor(concurrency: number = 3) { this.concurrency = concurrency; }

enqueue(task: Task<T>): void { this.queue.push(task); this.processNext(); }

private processNext(): void { while (this.activeCount < this.concurrency && this.queue.length > 0) { const task = this.queue.shift()!; this.activeCount++; task() .then(result => console.log('نجاح:', result)) .catch(error => console.error('خطأ:', error)) .finally(```

المدونات

توصيات الكتب