في مجتمع Android ، صادفت ثلاثة أنواع من المطورين الذين صادفوا RxRelay:
- أولئك الذين لا يفهمون سبب استخدام RxRelay في مشروعهم ، ولماذا هناك حاجة إليه وكيف يختلف عن الموضوع
- أولئك الذين يعتقدون أن RxRelay "يبتلع" أخطاء أو "بعد حدوث خطأ RxRelay ، سيستمر في العمل ، لكن الموضوع لن يفعل" (نفس السحر)
- أولئك الذين يعرفون حقًا ما هو RxRelay.
في حين أن النوعين الأولين أكثر شيوعًا ، قررت أن أكتب مقالة تساعدك على فهم كيفية عمل RxRelay والتحقق من خصائصه "السحرية".
إذا كنت تستخدم RxJava ، فمن المحتمل أنك تستخدم Subject أو RxRelay لرمي الأحداث من كيان إلى آخر أو إنشاء كود تفاعلي من التعليمات البرمجية الضرورية.
دعنا نتحقق من # 2 ونرى ما هو الفرق بين RxRelay والموضوع. لذلك ، لدينا اشتراكان في مرحل واحد ، عندما نضغط على الزر ، نضغط أحدهما على هذا الترحيل.
class MainActivity : AppCompatActivity() {
private val relay = PublishRelay.create<Int>()
private var isError: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val disposable1 = relay
.map {
if (isError) {
isError = false
throw Exception()
} else {
isError = true
}
}.subscribe(
{
Log.d("test", " : onNext")
},
{
Log.d("test", " : onError")
}
)
val disposable2 = relay
.subscribe(
{
Log.d("test", " : onNext")
},
{
Log.d("test", " : onError")
}
)
btn.setOnClickListener {
relay.accept(1)
}
}
}
نضغط على الزر ثلاث مرات متتالية ونرى مثل هذا السجل.
D / test: سلسلة بها خطأ: onNext
D / test: سلسلة بدون خطأ: onNext
D / test: Chain with error: onError
D / test: Chain without error: onNext
D / test: Chain without error: onNext
إذا استبدلت متغير RxRelay بـ PublishSubject ، لن يتغير السجل. وإليك السبب:
في النقرة الأولى ، نقوم بدفع البيانات إلى المرحل الخاص بنا. يتم تشغيل كلا المشتركين.
في النقرة الثانية في السلسلة ، يحصل المشترك الأول (المتاح 1) على خطأ.
في النقرة الثالثة ، لم يعد يتم تنشيط أول يمكن التخلص منه ، نظرًا لأنه تلقى الحالة الطرفية onError. عندئذٍ فقط سوف يعمل النوع الثاني القابل للتصرف 2.
سيكون هذا هو الحال مع الموضوع و RxRelay. اسمحوا لي أن أذكرك أنه في rx ، تنتقل الأخطاء إلى أسفل السلسلة إلى المشترك (المصب) وفوق المكان الذي حدثت فيه ، لا تحصل. انتهى الأمر بالتحقق من أن التسلسل المستند إلى RxRelay لا يمكن أن يعمل بعد حدوث الخطأ.
إذن ، إذا لم يكن هناك اختلاف في سلوك Subject و RxRelay ، فما هو الاختلاف بينهما؟
هذا ما يكتبه المطور بنفسه في README على github:
"بشكل أساسي: موضوع إلا بدون القدرة على استدعاء onComplete أو onError."
أي أنه مجرد موضوع بدون طريقتين onComplete و onError ، حتى شفرة المصدر للفئات هي نفسها تقريبًا. إذا استدعينا هذه الطرق على الموضوع ، فسيتوقف عن العمل ، لأنه سيتلقى حالة طرفية. لذلك ، قرر مؤلف المكتبة أن الأمر يستحق إزالة هذه الطرق ، لأن هؤلاء المطورين الذين لا يعرفون عن خاصية الموضوع هذه يمكنهم الاتصال بهم عن طريق الخطأ.
الخلاصة: الاختلاف الوحيد بين RxRelay والموضوع هو عدم وجود طريقتين onComplete و onError ، بحيث لا يستطيع المطور استدعاء الحالة الطرفية.