Summary of the implementation of various scenes in Rxjava _java

Source: Internet
Author: User
Tags class operator

Delaying the execution of an action

Can be implemented using the Timer+map method. The code is as follows:

Observable.timer (5, Timeunit.milliseconds). Map (value->{return
   dosomething ();
  }). Subscribe (system.out::p rintln);
 }

Ii. delayed delivery of implementation results

This scenario requires that the action that produces the data be executed immediately, but the result is deferred. This is not the same as the scene above.

This scenario can be used Observable.zip to implement.

The ZIP operator combines the data emitted by multiple observable in sequence, and each data can only be combined once, and is ordered. The number of data in the final combination is determined by the observable with the lowest emission data.

For each observable the same position of data, you need to wait for each other, it is said that the first observable the first position of the data generation, to wait for the second observable the first position of the data generation, and so observable the same location of the data are generated, Can be grouped by the specified rule. This is really what we're going to use.

Zip has many kinds of declarations, but it's roughly the same, by passing in several observable and then specifying a rule to process the data for each observable to produce a new data, one of the simplest:

 public static <t1, T2, r> observable<r> zip (observable<? extends T1>, O1 observable<? extends t2> O2, Final func2<? Super T1, huh? Super T2, huh? Extends r> zipfunction);

Push send with ZIP implementation results as follows:

 Observable.zip (Observable.timer (5,timeunit.milliseconds)
         , Observable.just (DoSomething ()), (x,y)->y)
   . Subscribe (System.out::p rintln));

Use defer to perform some kind of action in a specified thread

As the following code, although we specify how the thread will run, doSomething() This function is still executed in the thread that the current code calls.

 Observable.just (DoSomething ())
     . Subscribeon (Schedulers.io ())
     . Observeon (Schedulers.computation ())
     . Subscribe (V->utils.printlnwiththread (v.tostring ()););

Usually we use the following methods to achieve the goal:

 Observable.create (S->{s.onnext (DoSomething ());})
    . Subscribeon (Schedulers.io ())
    . Observeon (Schedulers.computation ())
    . Subscribe (v->{
     Utils.printlnwiththread (V.tostring ());
  

But in fact we use defer can also achieve the same goal.

About defer

The defer operator, like the Create, just, and from operators, creates the class operator, but all data associated with the operator is not valid until the subscription is subscribed.

Statement:

 public static <T> observable<t> defer (func0<observable<t>> observablefactory);

The observable in defer's Func0 is created when subscribing to (subscribe).

Role:

Do not create the observable until a Observer subscribes; Create a fresh observable on each subscription.

It is also said that observable was created at the time of subscription.

The above questions are implemented with defer:

 Observable.defer (()->observable.just (DoSomething ()))
    . Subscribeon (Schedulers.io ())
    . Observeon ( Schedulers.computation ())
    . Subscribe (V->{utils.printlnwiththread (v.tostring ());
  });

Iv. use compose do not interrupt chain-type structure

We often see the following code:

 Observable.just (DoSomething ())
    . Subscribeon (Schedulers.io ())
     . Observeon (Schedulers.computation ())
    . Subscribe (V->{utils.printlnwiththread (v.tostring ());

The code above may be the subscribeOn(xxx).observeOn(xxx) same in many places, and if we intend to unify it in a certain place, we can write this:

 private static <T> observable<t> applyschedulers (observable<t> observable) {return
  Observable.subscribeon (Schedulers.io ())
    . Observeon (Schedulers.computation ());
 }

But so each time we need to call the above method, roughly like the following, the outermost is a function, which is tantamount to breaking the link structure:

 Applyschedulers (Observable.from (somesource). Map (new Func1<data, data> () {
   @Override public data Call (data Data) {return
   manipulate (data);
   }
  })
 . Subscribe (new action1<data> () {
  @Override public void call (data data) {
  dosomething (data);
  }
 );

You can use the compose operator to achieve the goal of not breaking the link structure.

Compose's statement is as follows:

 Public observable compose (TRANSFORMER< Super T,? extends r> Transformer);

Its input parameter is a transformer interface, and the output is a observable. and transformer is actually one Func1<Observable<T> , in Observable<R>> other words: It is possible to convert one type of observable to another type of observable.

Simply put, compose can convert the original observable to another observable by the specified transformation (input parameter transformer).

With compose, you specify the threading method in the following ways:

 private static <T> transformer<t, t> applyschedulers () {return
   new transformer<t, t> () {
    @ Override public
    observable<t> call (observable<t> observable) {return
     Observable.subscribeon ( Schedulers.io ())
       . Observeon (Schedulers.computation ());}}
   ;
  }

 Observable.just (DoSomething ()). Compose (Applyschedulers ())
    . Subscribe (V->{utils.printlnwiththread ( V.tostring ());
   

function applyschedulers can be further simplified using lambda expressions as follows:

 private static <T> transformer<t, t> applyschedulers () {return 
  observable-> Observable.subscribeon (Schedulers.io ())
    . Observeon (Schedulers.computation ());
 }

V. Use different execution results by priority

The title above does not make it clear what I want to say. In fact, I would like to express the scene similar to the usual access to the network data scene: If the cache has, from the cache to get, if not, then from the network to obtain.

This requires that if the cache is there, it will not do the action of fetching data from the network.

This can be implemented using Concat+first.

Concat combines several observable into a observable to return to the final observable. And that data is just like sending it from a observable. The parameter can be multiple observable, or it can be a iterator containing observalbe.

The data in the new observable is arranged in the order of the observable in the original concat, that is, the data in the new result is sorted in the original order.

Here is the implementation of the above requirements:

 Observable.concat (Getdatafromcache (), Getdatafromnetwork ()). A ()
    . Subscribe (V->SYSTEM.OUT.PRINTLN (" Result: "+v)");
 Get data from cache
 private static observable<string> Getdatafromcache () {return
  observable.create (s-> {
   //dosomething to get data
   int value = new Random (). Nextint ();
   Value = value%2;
   if (value!=0) {
    s.onnext ("Data from cache:" +value); Generate Data
   }
   //s.onerror (new Throwable ("none"));
   S.oncompleted ();
  }
    );
 Get data from the network
 private static observable<string> getdatafromnetwork () {return
  observable.create (s-> { for
   (int i = 0; i < i++) {
    utils.println ("OBS2 generate" +i);
    S.onnext ("Data from Network:" + i); Generate Data
   }
   s.oncompleted ();
  }
 

The above implementation, if Getdatafromcache has the data, getdatafromnetwork the code here is not executed, this is exactly what we want.

The above implementation has several needs to note:

1, it is possible to get no data from two places, this scenario using first will throw an exception nosuchelementexception, if this is the case, you need to replace the top one with FirstOrDefault.

2, above getDataFromCache() , if there is no data, we call the oncompleted directly, if not call oncompleted, but call onerror, then the above concat is not any results. Because the concat received any error, The merge will stop. Therefore, if you want to use onerror, you need to use the Concatdelayerror substitution concat.concatDelayError will first ignore the error, the error deferred to the final processing.

Summarize

The above is the entire content of this article, I hope the content of this article for everyone's study or work can bring certain help, if you have questions you can message exchange.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.