1. ชะลอการดำเนินการดำเนินการ
สามารถนำไปใช้งานได้โดยใช้วิธีการจับเวลา+แผนที่ รหัสมีดังนี้:
สังเกตได้. timer (5, timeunit.milliseconds) .map (ค่า-> {return dosomething ();}) สมัครสมาชิก (System.out :: println); - 2. ล่าช้าผลการส่ง
สถานการณ์นี้กำหนดให้การดำเนินการของการสร้างข้อมูลจะถูกดำเนินการทันที แต่ผลลัพธ์จะล่าช้าในการส่ง สิ่งนี้แตกต่างจากสถานการณ์ข้างต้น
สถานการณ์นี้สามารถนำไปใช้งานได้โดยใช้ Observable.zip
ตัวดำเนินการ ZIP รวมข้อมูลที่ส่งผ่านหลายรายการตามลำดับข้อมูลแต่ละข้อมูลสามารถรวมกันได้เพียงครั้งเดียวและพวกเขาทั้งหมดสั่ง จำนวนข้อมูลรวมสุดท้ายจะถูกกำหนดโดยที่สังเกตได้ซึ่งส่งข้อมูลน้อยที่สุด
สำหรับข้อมูลในตำแหน่งเดียวกันของแต่ละที่สังเกตได้คุณต้องรอซึ่งกันและกัน กล่าวคือหลังจากที่ข้อมูลในตำแหน่งแรกของการสังเกตแรกถูกสร้างขึ้นคุณต้องรอข้อมูลในตำแหน่งแรกของที่สองที่สังเกตได้ที่จะสร้างและหลังจากข้อมูลในตำแหน่งเดียวกันของแต่ละที่สังเกตได้ถูกสร้างขึ้นคุณสามารถรวมตามกฎที่ระบุ นี่คือสิ่งที่เราต้องการใช้จริงๆ
มีการประกาศหลายชนิดใน ZIP แต่มันก็เหมือนกันซึ่งจะผ่านไปในหลาย ๆ ข้อสังเกตจากนั้นระบุกฎเพื่อประมวลผลข้อมูลที่ตำแหน่งที่สอดคล้องกันของแต่ละที่สังเกตได้และสร้างข้อมูลใหม่ นี่คือหนึ่งในสิ่งที่ง่ายที่สุด:
สาธารณะคงที่ <t1, t2, r> ที่สังเกตได้ <r> zip (สังเกตได้ <? ขยาย t1> o1, สังเกตได้ <? ขยาย t2> o2, func2 สุดท้าย <? super t1,? super t2,? ขยาย r> zipfunction);
ผลการดำเนินการของการกดและส่งโดยใช้ zip มีดังนี้:
สังเกตได้ zip (สังเกตได้. timer (5, timeunit.milliseconds), สังเกตได้เพียงแค่ (dosomething ()), (x, y)-> y) .subscribe (system.out :: println));
3. ใช้การเลื่อนเวลาเพื่อดำเนินการบางอย่างในเธรดที่ระบุ
เช่นเดียวกับในรหัสต่อไปนี้แม้ว่าเราจะระบุวิธีการรันของเธรด แต่ฟังก์ชั่น doSomething() ยังคงดำเนินการในเธรดที่เรียกโดยรหัสปัจจุบัน
สังเกตได้เพียงแค่ (dosomething ()) .subscribeon (schedulers.io ()) .observeon (schedulers.computation ()) .subscribe (v-> utils.printlnwiththread (v.tostring ()););
โดยปกติเราจะใช้วิธีการต่อไปนี้เพื่อให้บรรลุเป้าหมายของเรา:
สังเกตได้. สร้าง (s-> {s.onnext (dosomething ());}) .subscribeon (schedulers.io ()) .observeon (schedulers.computation ()) .subscribe (v-> {utils.printlnwiththread (v.tostring ();};แต่ในความเป็นจริงเราสามารถบรรลุเป้าหมายเดียวกันโดยใช้การเลื่อนเวลา
เกี่ยวกับการเลื่อนเวลา
ตัวดำเนินการที่เลื่อนออกไปนั้นเหมือนกับการสร้างเพียงจากและตัวดำเนินการอื่น ๆ มันสร้างตัวดำเนินการในชั้นเรียน แต่ข้อมูลทั้งหมดที่เกี่ยวข้องกับตัวดำเนินการนี้จะมีผลเฉพาะเมื่อคุณสมัครสมาชิก
คำแถลง:
สาธารณะคงที่ <T> ที่สังเกตได้ <t> การเลื่อนเวลา (func0 <สังเกตได้ <t>> สังเกตการณ์ได้);
สิ่งที่สังเกตได้ใน FunC0 ของ Delfer นั้นถูกสร้างขึ้นเมื่อสมัครสมาชิกเท่านั้น
ผล:
อย่าสร้างสิ่งที่สังเกตได้จนกว่าผู้สังเกตการณ์จะสมัครสมาชิก สร้างสิ่งที่สังเกตได้ใหม่ในการสมัครสมาชิกแต่ละครั้ง
กล่าวอีกนัยหนึ่งที่สังเกตได้ถูกสร้างขึ้นเมื่อสมัครรับสมัคร
ปัญหาข้างต้นถูกนำไปใช้กับการเลื่อนเวลา:
สังเกตได้. defer (()-> สังเกตได้เพียงแค่ (dosomething ())) .subscribeon (schedulers.io ()) .observeon (schedulers.computation ()) .subscribe (v-> {utils.printlnwiththread (v.tostring ());}; 4. อย่าทำลายโครงสร้างห่วงโซ่โดยใช้การเขียน
เรามักจะเห็นรหัสต่อไปนี้:
สามารถสังเกตได้เพียงแค่ (dosomething ()) .subscribeon (schedulers.io ()) .observeon (schedulers.computation ()) .subscribe (v-> {utils.printlnwiththread (v.toString ()); ในรหัสข้างต้น subscribeOn(xxx).observeOn(xxx) อาจเหมือนกันในหลาย ๆ ที่ หากเราวางแผนที่จะนำไปใช้ในสถานที่หนึ่งเราสามารถเขียนได้เช่นนี้:
ส่วนตัวคงที่ <t> ที่สังเกตได้ <t> applyschedulers (สังเกตได้ <t> สามารถสังเกตได้) {return สามารถสังเกตได้ subscribeonon (schedulers.io ()) .observeon (schedulers.computation ()); -แต่ทุกครั้งที่เราจำเป็นต้องเรียกวิธีการข้างต้นมันจะเป็นไปตามสิ่งต่อไปนี้และด้านนอกสุดเป็นฟังก์ชั่นซึ่งเทียบเท่ากับการทำลายโครงสร้างลิงก์:
applyschedulers (สังเกตได้จาก (somesource) .map (func1 ใหม่ <data, data> () {@Override การเรียกข้อมูลสาธารณะ (ข้อมูลข้อมูล) {ส่งคืนการจัดการ (ข้อมูล);}})). subsribe (action1 <data> (data> ()ผู้ประกอบการ Compose สามารถใช้เพื่อให้บรรลุวัตถุประสงค์ของการไม่ทำลายโครงสร้างลิงก์
คำแถลงการแต่งเพลงมีดังนี้:
Public Wereable Compose (Transformer <? super t,? ขยาย r> transformer);
พารามิเตอร์ที่เข้ามาคืออินเทอร์เฟซของหม้อแปลงและเอาต์พุตเป็นสิ่งที่สังเกตได้ Transformer เป็น Func1<Observable<T> , Observable<R>> กล่าวอีกนัยหนึ่ง: สามารถแปลงที่สังเกตได้ประเภทหนึ่งเป็นประเภทอื่นที่สังเกตได้
พูดง่ายๆคือการเขียนสามารถแปลงต้นฉบับที่สังเกตได้เป็นสิ่งที่สังเกตได้อื่นผ่านวิธีการแปลงที่ระบุ (หม้อแปลงพารามิเตอร์อินพุต)
ผ่านการเขียนให้ใช้วิธีการต่อไปนี้เพื่อระบุวิธีเธรด:
ส่วนตัวคงที่ <t> หม้อแปลง <t, t> applyschedulers () {ส่งคืนหม้อแปลงใหม่ <t, t> () {@Override สาธารณะที่สังเกตได้ <t> การโทร (สังเกตได้ <t> สามารถสังเกตได้) {ส่งคืนได้ - } สังเกตได้. Just (dosomething ()). pospose (applyschedulers ()) .subscribe (v-> {utils.printlnwithThread (v.toString ());});ฟังก์ชั่น applyschedulers สามารถทำให้ง่ายขึ้นโดยใช้นิพจน์แลมบ์ดาเป็นสิ่งต่อไปนี้:
ส่วนตัวคงที่ <t> หม้อแปลง <t, t> applyschedulers () {return neverablable-> deplowable.subscribeon (schedulers.io ()) .observeon (schedulers.computation ()); - 5. ใช้ผลการดำเนินการที่แตกต่างกันตามลำดับความสำคัญ
ชื่อด้านบนอาจไม่ได้แสดงสถานการณ์ที่ฉันต้องการแสดงอย่างชัดเจน ในความเป็นจริงสถานการณ์ที่ฉันต้องการแสดงนั้นคล้ายกับสถานการณ์ปกติของการได้รับข้อมูลเครือข่าย: หากมีแคชมันจะได้รับจากแคชและหากไม่มีมันจะได้รับจากเครือข่าย
จำเป็นต้องมีที่นี่หากมีแคชการกระทำของการรับข้อมูลจากเครือข่ายจะไม่ถูกดำเนินการ
สิ่งนี้สามารถนำไปใช้โดยใช้ concat+ก่อน
Concat ผสานการสังเกตหลายอย่างเป็นหนึ่งเดียวที่สังเกตได้และส่งคืนสิ่งที่สังเกตได้สุดท้าย และข้อมูลเหล่านั้นก็เหมือนกับการส่งจากสิ่งที่สังเกตได้ พารามิเตอร์อาจเป็นหลายสิ่งที่สังเกตได้หรือตัววนซ้ำที่มีการสังเกต
ข้อมูลในการสังเกตใหม่จะถูกจัดเรียงตามลำดับของสิ่งที่สังเกตได้ใน concat ดั้งเดิมนั่นคือข้อมูลในผลลัพธ์ใหม่จะถูกเรียงลำดับตามลำดับดั้งเดิม
ต่อไปนี้คือการดำเนินการตามข้อกำหนดข้างต้น:
สังเกตได้. concat (getDataFromCache (), getDataFromNetWork ()). First () .Subscribe (v-> system.out.println ("ผลลัพธ์:"+v)); // รับข้อมูลจากแคชส่วนตัวคงที่ <string> getDataFromCache () {return observable.create (s -> {// dosomething เพื่อรับข้อมูล int value = new sandom (). nextint () ค่า = ค่า%2; ถ้า (ค่า! = 0) {s.onnext (" s.oncompleted ();}); } // รับข้อมูลจากเครือข่ายส่วนตัวที่สังเกตได้ <string> getDataFromNetWork () {return neverbable.create (s -> {สำหรับ (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 จะเพิกเฉยต่อข้อผิดพลาดก่อนและเลื่อนข้อผิดพลาดจนกว่าการประมวลผลจะสิ้นสุด
สรุป
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่าเนื้อหาของบทความนี้จะช่วยในการศึกษาหรือทำงานของคุณ หากคุณมีคำถามใด ๆ คุณสามารถฝากข้อความไว้เพื่อสื่อสาร