| الجانب الهندسي (`Architectural Aspect`) | السلوك الداخلي في النظام | الفائدة المباشرة في معمارية التطبيق |
|---|---|---|
| عزل التنفيذ لكل مستهلك (`Execution Isolation`) | كل عملية `subscribe` تنشئ نسخة تنفيذ مستقلة تماماً للـ Observable (Cold Observable) | ضمان عدم تداخل البيانات بين المكونات المختلفة التي تستخدم نفس المصدر |
| معالجة الأخطاء الآمنة (`Error Containment`) | وقوع خطأ في قناة `error` يوقف التدفق نهائياً ويغلق الاتصال تلقائياً | حماية واجهة المستخدم من الدخول في حالات حرجة أو لا متناهية عند فشل الاتصال بالخادم |
| إدارة التخلص من الموارد (`Resource Teardown`) | إمكانية إرجاع دالة تنظيف مخصصة داخل الـ Observable (`return () => { ... }`) | تنفيذ مهام الإغلاق (مثل إيقاف المؤقتات أو اتصالات WebSocket) فور انتهاء الاشتراك |
يُعتبر فهم العناصر الثلاثة الأساسية في مكتبة RxJS بمثابة حجر الأساس لأي مطور تروس تفاعلية. هذه العناصر هي: Observable (المنتج أو مصدر البيانات)، Observer (المستهلك أو من يتلقى البيانات)، و Subscription (عقد الربط والدعم الذي يدير دورة حياة الاتصال). استيعاب هذا الثلاثي يمنحك السطوة الكاملة على تدفقات البيانات غير المتزامنة بأسلوب هندسي محترف.
عند إنشاء Observable يدويًا، يمكنك إرجاع دالة داخل الـ producer لتنفيذ أي إجراءات تنظيف (مثل clearInterval أو إلغاء اتصال شبكي) فور استدعاء .unsubscribe()، مما يرفع من جودة وكفاءة الكود.
يمكنك تمرير الدوال مباشرة إلى .subscribe(next, error, complete) دون الحاجة لتعريف كائن مراقب منفصل، وهو النمط الأكثر شيوعاً واختصاراً في تطوير أنجولر اليومي مع الحفاظ على كامل الكفاءة البرمجية.
| 1 | import { Component, OnInit, OnDestroy } from '@angular/core'; |
| 2 | import { CommonModule } from '@angular/common'; |
| 3 | import { Subscription } from 'rxjs'; |
| 4 | |
| 5 | @Component({ |
| 6 | selector: 'app-advanced-observable', |
| 7 | standalone: true, |
| 8 | imports: [CommonModule], |
| 9 | template: ` |
| 10 | <div class="advanced-observable-card"> |
| 11 | <h3>التحكم الهندسي المتقدم في دورة حياة الـ Observables</h3> |
| 12 | |
| 13 | <div class="metrics-display-box"> |
| 14 | <p><strong>قيمة العداد المتقدم:</strong> {{ counterValue }}</p> |
| 15 | <p><strong>حالة الموارد الخلفية:</strong> <span class="resource-active">مُدارة وآمنة</span></p> |
| 16 | </div> |
| 17 | </div> |
| 18 | `, |
| 19 | styles: [` |
| 20 | .advanced-observable-card { background: #090d16; color: #fff; padding: 24px; border-radius: 12px; border: 1px solid #1e293b; } |
| 21 | .metrics-display-box { background: #1e293b; border: 1px solid #334155; padding: 16px; border-radius: 8px; } |
| 22 | .metrics-display-box p { margin: 8px 0; color: #94a3b8; } |
| 23 | .metrics-display-box strong { color: #38bdf8; } |
| 24 | .resource-active { color: #10b981; font-weight: bold; } |
| 25 | `] |
| 26 | }) |
| 27 | export class AdvancedObservableComponent implements OnInit, OnDestroy { |
| 28 | counterValue: number = 0; |
| 29 | private timerSubscription!: Subscription; |
| 30 | |
| 31 | ngOnInit(): void { |
| 32 | // إنشاء Observable مخصص مع دالة تنظيف داخلية (Teardown Logic) |
| 33 | const secureTimer$ = new Observable<number>((subscriber) => { |
| 34 | let count = 0; |
| 35 | |
| 36 | // تشغيل مؤقت زمني خلفي |
| 37 | const intervalId = setInterval(() => { |
| 38 | count++; |
| 39 | subscriber.next(count); |
| 40 | console.log('إصدار قيمة دورية:', count); |
| 41 | }, 1000); |
| 42 | |
| 43 | // دالة التنظيف التلقائي التي تعمل فور إلغاء الاشتراك |
| 44 | return () => { |
| 45 | clearInterval(intervalId); |
| 46 | console.log('تم تنظيف وإيقاف المؤقت الخلفي بنجاح تام لتفادي تسريب الذاكرة.'); |
| 47 | }; |
| 48 | }); |
| 49 | |
| 50 | // الاشتراك في التدفق ومعالجة البيانات عبر الـ Observer المختصر |
| 51 | this.timerSubscription = secureTimer$.subscribe({ |
| 52 | next: (val) => { |
| 53 | this.counterValue = val; |
| 54 | }, |
| 55 | error: (err) => console.error('خطأ في التدفق:', err), |
| 56 | complete: () => console.log('اكتمل التدفق بنجاح.') |
| 57 | }); |
| 58 | } |
| 59 | |
| 60 | ngOnDestroy(): void { |
| 61 | // إلغاء الاشتراك يؤدي تلقائياً لتفعيل دالة التنظيف (Teardown) في الأعلى |
| 62 | if (this.timerSubscription) { |
| 63 | this.timerSubscription.unsubscribe(); |
| 64 | } |
| 65 | } |
| 66 | } |