1. تأخير إجراء التنفيذ
يمكن تنفيذها باستخدام طريقة Timer+Map. الرمز كما يلي:
Observable.Timer (5 ، timeUnit.milliseconds) .map (value-> {return dosomething () ؛}). الاشتراك (system.out :: println) ؛ } 2. تأخير نتيجة إرسال
يتطلب هذا السيناريو تنفيذ إجراء توليد البيانات على الفور ، ولكن يتم تأخير النتيجة في الإرسال. هذا يختلف عن السيناريو أعلاه.
يمكن تنفيذ هذا السيناريو باستخدام Observable.zip .
يجمع مشغل ZIP بين البيانات التي يتم نقلها بواسطة العديد من المراكز بالترتيب ، لا يمكن دمج كل بيانات إلا مرة واحدة ، ويتم طلبها جميعًا. يتم تحديد عدد البيانات المدمجة النهائية من خلال الملاحظة ، والتي تنقل أقل البيانات.
بالنسبة للبيانات في نفس الموقع لكل منها ، تحتاج إلى انتظار بعضها البعض. وهذا يعني ، بعد إنشاء البيانات في الموقع الأول من الأول الذي يمكن ملاحظته ، يجب أن تنتظر البيانات في الموقع الأول للملاحظة التي يمكن ملاحظتها ، وبعد إنشاء البيانات في نفس موقع كل قابلة للملاحظة ، يمكنك الجمع وفقًا للقواعد المحددة. هذا حقًا ما نريد استخدامه.
هناك أنواع كثيرة من الإعلانات في ZIP ، ولكنها هي نفسها تقريبًا ، والتي تتمرير في العديد من الملاحظات ، ثم حدد قاعدة لمعالجة البيانات في الموقع المقابل لكل ، وإنشاء بيانات جديدة. هنا واحدة من أبسط:
static public <T1 ، T2 ، r> يمكن ملاحظتها <r> zip (يمكن ملاحظتها <؟ تمتد T1> O1 ، يمكن ملاحظتها <؟ تمتد T2> O2 ، Func2 النهائي <؟ Super T1 ،؟ Super T2 ،؟ تمتد r> zipfunction) ؛
نتائج تنفيذ الدفع والإرسال باستخدام ZIP هي كما يلي:
opplicable.zip (rocartable.timer (5 ، timeUnit.milliseconds) ، يمكن ملاحظته.
3. استخدم التأجيل لأداء إجراءات معينة في الموضوع المحدد
كما هو الحال في الكود التالي ، على الرغم من أننا نحدد طريقة تشغيل مؤشر الترابط ، إلا أنه لا يزال يتم تنفيذ وظيفة doSomething() في مؤشر الترابط الذي يطلق عليه الرمز الحالي.
يمكن ملاحظته. just (dosomething ()) .Subscribeon (Schedulers.io ()) .Observeon (Schedulers.computation ()) .Subscribe (v-> utils.printlnwithThread (v.toString ()) ؛) ؛
عادة ما نستخدم الطرق التالية لتحقيق هدفنا:
rocartable.create (s-> {s.onnext (dosomething ()) ؛}) .Subscribeon (Schedulers.io ()) .Observeon (Schedulers.computation ()) .Subscribe (V-> {utils.printlnwiththroad (v.toString ()) ؛}) ؛ولكن في الواقع ، يمكننا تحقيق نفس الهدف باستخدام التأجيل.
حول التأجيل
المشغل المؤجل هو نفسه إنشاء ، فقط ، من المشغلين وغيرهم. إنه ينشئ عوامل فئة ، لكن جميع البيانات المتعلقة بهذا المشغل لا تسري إلا إذا اشتركت.
إفادة:
static public <T> يمكن ملاحظته <T> مؤجلة (func0 <T >> قابلية للملاحظة) ؛
يتم إنشاء الملاحظة في مؤشر FUNC0 فقط عند الاشتراك.
تأثير:
لا تنشئ الملاحظة حتى يشترك مراقب ؛ إنشاء طازجة يمكن ملاحظتها على كل اشتراك.
وبعبارة أخرى ، يتم إنشاء الملاحظة عند الاشتراك.
يتم تنفيذ المشكلة أعلاه مع تأجيل:
rocartable.defer (()-> rocartable.just (dosomething ())) .subscribeon (Schedulers.io ()) .Observeon (Schedulers.computation ()) .SubScribe (v-> {utils.printlnwiththread (v.toString ()) ؛}) ؛ 4. لا تكسر بنية السلسلة باستخدام تأليف
غالبًا ما نرى الكود التالي:
rocartable.just (dosomething ()) .Subscribeon (Schedulers.io ()) .Observeon (Schedulers.computation ()) .SubScribe (V-> {utils.printlnwithThread (v.toString ()) ؛ في الكود أعلاه ، قد يكون subscribeOn(xxx).observeOn(xxx) هو نفسه في العديد من الأماكن. إذا خططنا لتنفيذها في مكان معين ، فيمكننا كتابته مثل هذا:
ثابت خاص <T> يمكن ملاحظته <T> تطبيقات (يمكن ملاحظته <T> قابلة للملاحظة) {return robarleable.subscribeon (Schedulers.io ()) .Observeon (Schedulers.computation ()) ؛ }ولكن في كل مرة نحتاج إلى استدعاء الطريقة أعلاه ، سيكون الأمر مثل ما يلي تقريبًا ، والأقرف الخارجية هي وظيفة ، وهي مكافئة لكسر بنية الارتباط:
applictScheDulers (قابلة للملاحظة. from (somesource) .map (func1 جديد <البيانات ، البيانات> () {Override استدعاء البيانات العامة (بيانات البيانات) {return manipulate (data) ؛}})يمكن استخدام عامل التأليف لتحقيق الغرض من عدم كسر بنية الارتباط.
بيان التأليف كما يلي:
Compose للملاحظة العامة (Transformer <؟ super t ،؟ يمتد R> transformer) ؛
المعلمة الواردة لها هي واجهة محول والإخراج يمكن ملاحظته. المحول هو في الواقع Func1<Observable<T> ، Observable<R>> ، بمعنى آخر: يمكن تحويل نوع واحد من الملاحظة إلى نوع آخر يمكن ملاحظته.
ببساطة ، يمكن لتكوين تحويل الأصل يمكن ملاحظته إلى آخر يمكن ملاحظته من خلال طريقة التحويل المحددة (محول معلمة الإدخال).
من خلال Compose ، استخدم الطريقة التالية لتحديد طريقة مؤشر الترابط:
static private <T> transformer <T ، t> applicsChedulers () {return new Transformer <t ، t> () {Override public callable <T> call (يمكن ملاحظته <T> قابلة للملاحظة) {return rocreadable.subscribeon (Schedulers.io ()) .Observeon (Schedulers.computation ()) ؛ }} ؛ } قابلة للملاحظة.يمكن تبسيط الدالة التي تنطبق على تعبيرات Lambda إلى ما يلي:
static private <T> transformer <T ، t> applicschedulers () {return roball-> opplication.subscribeon (Schedulers.io ()) .Observeon (Schedulers.computation ()) ؛ } 5. استخدم نتائج التنفيذ المختلفة وفقًا للأولوية
من المحتمل أن العنوان أعلاه لم يعبر عن السيناريو الذي أردت التعبير عنه بوضوح. في الواقع ، فإن السيناريو الذي أريد التعبير عنه يشبه السيناريو المعتاد للحصول على بيانات الشبكة: إذا كان هناك ذاكرة التخزين المؤقت ، فسيتم الحصول عليها من ذاكرة التخزين المؤقت ، وإذا لم يكن هناك ، فسيتم الحصول عليها من الشبكة.
مطلوب هنا أنه إذا كان هناك ذاكرة التخزين المؤقت ، فلن يتم تنفيذ إجراء الحصول على البيانات من الشبكة.
يمكن تنفيذ ذلك باستخدام Concat+أولاً.
يدمج Concat العديد من الملاحظات في واحدة يمكن ملاحظتها وإرجاع النهائي يمكن ملاحظته. وتلك البيانات مثل إرسالها من الملاحظة. يمكن أن تكون المعلمات ملاحظات متعددة أو متكررة تحتوي على oscersalbe.
يتم ترتيب البيانات الموجودة في الجديد القابل للملاحظة بترتيب الملاحظة في المسلسل الأصلي ، أي أن البيانات في النتيجة الجديدة يتم فرزها بالترتيب الأصلي.
فيما يلي تنفيذ المتطلبات المذكورة أعلاه:
rocartable.concat (getDataFromCache () ، getDataFromNetwork ()). أولاً () .subscribe (v-> system.out.println ("النتيجة:"+v)) ؛ // احصل على بيانات من ذاكرة التخزين المؤقت الثابتة الثابتة التي يمكن ملاحظتها <string> getDataFromCache () {return robarleable.create (s -> {// dosomething للحصول على قيمة int data = new Random (). S.Oncompleted () ؛ } // احصل على بيانات من الشبكة الخاصة الثابتة التي يمكن ملاحظتها <string> getDataFromNetwork () {return oundable.create (s -> {for (int i = 0 ؛ i <10 ؛ i ++) {utils.println ("obs2 generate"+i) ؛ }في التنفيذ أعلاه ، إذا كان GetDataFromCache يحتوي على بيانات ، فلن يتم تنفيذ الكود هنا في getDataFromNetwork ، وهذا بالضبط ما نريد.
هناك العديد من التطبيقات أعلاه التي تحتاج إلى الاهتمام:
1. من الممكن أن لا يمكن الحصول على البيانات من كلا المكانين. في هذا السيناريو ، سيؤدي استخدام أولاً إلى إلقاء استثناء nosuchelementException. إذا كان هذا السيناريو هو الحال ، فأنت بحاجة إلى استبدال الأول أعلاه بـ FirstorDefault.
2. في getDataFromCache() أعلاه ، إذا لم تكن هناك بيانات ، فإننا نسمي onCompleted مباشرة. إذا لم ندعو onCompleted ولكن استدعاء onerror ، فإن الاستخدام المذكور أعلاه من Concat لن يحصل على أي نتائج. لأنه عندما يتلقى Concat أي خطأ ، سيتوقف الدمج. لذلك ، إذا كنت ترغب في استخدام onerror ، فأنت بحاجة إلى استخدام concatdelayerror بدلاً من concat.concatDelayError سيتجاهل concatdelayerror الخطأ أولاً وتأجيل الخطأ حتى المعالجة النهائية.
لخص
ما سبق هو المحتوى الكامل لهذه المقالة. آمل أن يكون محتوى هذه المقالة من بعض المساعدة لدراستك أو عملك. إذا كان لديك أي أسئلة ، فيمكنك ترك رسالة للتواصل.