هل RxRelay سحر؟ الموضوع مقابل RxRelay





في مجتمع Android ، صادفت ثلاثة أنواع من المطورين الذين صادفوا RxRelay:



  1. أولئك الذين لا يفهمون سبب استخدام RxRelay في مشروعهم ، ولماذا هناك حاجة إليه وكيف يختلف عن الموضوع
  2. أولئك الذين يعتقدون أن RxRelay "يبتلع" أخطاء أو "بعد حدوث خطأ RxRelay ، سيستمر في العمل ، لكن الموضوع لن يفعل" (نفس السحر)
  3. أولئك الذين يعرفون حقًا ما هو 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 ، بحيث لا يستطيع المطور استدعاء الحالة الطرفية.



All Articles