| وجه المقارنة | البرمجة التقليدية (`Imperative Programming`) | البرمجة التفاعلية (`Reactive Programming`) |
|---|---|---|
| طريقة معالجة البيانات | تنفيذ الأوامر خطوة بخطوة عند طلبها يدوياً | التعامل مع البيانات كتدفق مستمر يتم الاستماع إليه والتفاعل معه لحظياً |
| الاستجابة للأحداث | تتطلب ربط مستمعات أحداث DOM يدوياً وكتابة منطق معقد لتحديث الحالة | اعتماد تصريحي كامل (`Declarative`) عبر مكتبة RxJS وربط التدفقات ببعضها |
| إدارة الحالة والتعقيد | تصبح معقدة وصعبة الصيانة مع تداخل العمليات غير المتزامنة | أبسط وأكثر تنظيماً بفضل فصل مصدر البيانات عن المستهلك |
تُعد البرمجة التفاعلية (Reactive Programming) النمط الأساسي الذي تُبنى عليه كافة العمليات غير المتزامنة وتدفقات البيانات. على عكس البرمجة التقليدية التي تعتمد على تنفيذ الأوامر بشكل تسلسلي جامد، تعتمد البرمجة التفاعلية على تدفقات البيانات المستمرة (Data Streams) وردود الأفعال اللحظية، مما يجعل التطبيق حياً وقادراً على الاستجابة لتغيرات واجهة المستخدم أو خادم البيانات بسلاسة فائقة وكفاءة هندسية عالية.
كل شيء في أنجولر يمكن اعتباره تدفقاً للبيانات: نقرات المستخدم، طلبات الـ HTTP، قيم حقول الإدخال، وحتى الأحداث الزمنية. مكتبة RxJS توفر الأدوات القياسية للتعامل مع هذه التدفقات بكفاءة مذهلة.
بدلاً من إخبار التطبيق بكل خطوة يجب تنفيذها يدويًا (Imperative)، تقوم بتعريف شكل تدفق البيانات وكيفية معالجتها عند حدوث التغيير (Declarative)، مما يقلل الأخطاء البرمجية ويسهل قراءة الكود.
| 1 | import { Component, OnInit, OnDestroy } from '@angular/core'; |
| 2 | import { CommonModule } from '@angular/common'; |
| 3 | import { interval, Subject, takeUntil } from 'rxjs'; |
| 4 | |
| 5 | @Component({ |
| 6 | selector: 'app-reactive-intro', |
| 7 | standalone: true, |
| 8 | imports: [CommonModule], |
| 9 | template: ` |
| 10 | <div class="reactive-intro-container"> |
| 11 | <h3>مفهوم البرمجة التفاعلية وتدفق البيانات الزمني</h3> |
| 12 | |
| 13 | <div class="stream-status-box"> |
| 14 | <p><strong>العداد التفاعلي اللحظي:</strong> {{ currentStreamValue }}</p> |
| 15 | <p><strong>حالة الاستجابة:</strong> <span class="status-active">نشط ومتصل تلقائياً</span></p> |
| 16 | </div> |
| 17 | </div> |
| 18 | `, |
| 19 | styles: [` |
| 20 | .reactive-intro-container { background: #090d16; color: #fff; padding: 24px; border-radius: 12px; border: 1px solid #1e293b; } |
| 21 | .stream-status-box { background: #1e293b; border: 1px solid #334155; padding: 16px; border-radius: 8px; } |
| 22 | .stream-status-box p { margin: 8px 0; color: #94a3b8; } |
| 23 | .stream-status-box strong { color: #38bdf8; } |
| 24 | .status-active { color: #10b981; font-weight: bold; } |
| 25 | `] |
| 26 | }) |
| 27 | export class ReactiveIntroComponent implements OnInit, OnDestroy { |
| 28 | currentStreamValue: number = 0; |
| 29 | private destroy$ = new Subject<void>(); |
| 30 | |
| 31 | ngOnInit(): void { |
| 32 | // إنشاء تدفق زمني مستمر يصدر قيماً كل ثانية (يمثل نموذج البرمجة التفاعلية) |
| 33 | interval(1000).pipe( |
| 34 | takeUntil(this.destroy$) // إدارة الذاكرة ومنع التسريب تلقائياً عند تدمير المكون |
| 35 | ).subscribe(value => { |
| 36 | this.currentStreamValue = value; |
| 37 | console.log('تم استقبال قيمة جديدة من التدفق التفاعلي:', value); |
| 38 | }); |
| 39 | } |
| 40 | |
| 41 | ngOnDestroy(): void { |
| 42 | // إغلاق التدفق لتنظيف الموارد بشكل هندسي سليم |
| 43 | this.destroy$.next(); |
| 44 | this.destroy$.complete(); |
| 45 | } |
| 46 | } |
⚠️ تحذير
لا تتعامل مع العمليات غير المتزامنة بالطرق التقليدية العشوائية! الاعتماد على الـ Callbacks المتداخلة أو المتغيرات المتفرقة ينهك هيكل التطبيق ويصعب تتبع الأخطاء، لذا فإن الالتزام بنمط البرمجة التفاعلية الموحد هو الضمان الوحيد لاستقرار التطبيق على المدى الطويل.