Rxjava lazy load, careful use of custom operators, giving priority to built-in operators __java

Source: Internet
Author: User

I am increasingly interested in using the Rxjava defer () operator as a tool to ensure that observable code is not executed until it is subscribed (rather than immediately after it is created). I've written some code about defer () before, but now I want to describe it in more detail.

Suppose that there is a data class:

<code class= "HLJS cs has-numbering" style= "Display:block"; padding:0px; Color:inherit; Box-sizing:border-box; font-family: ' Source Code Pro ', monospace;font-size:undefined; White-space:pre; border-radius:0px; Word-wrap:normal; background:transparent; " ><span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); Box-sizing:border-box; " >public</span> <span class= "Hljs-keyword" style= "Color:rgb (0, 0, 136); Box-sizing:border-box; " >class</span> SomeType {<span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); box-sizing:border-box; " >private</span> String <span class= "Hljs-keyword" style= "Color:rgb (0, 0, 136); Box-sizing:border-box; "

>value</span>; <span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); Box-sizing:border-box; " >public</span> <span class= "Hljs-keyword" style= "Color:rgb (0, 0, 136); Box-sizing:border-box; " >void</span> <span class= "Hljs-title" style= "Box-sizing:border-box;" >setvaLue</span> (String <span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); box-sizing:border-box; " >value</span>) {<span class= "Hljs-keyword" style= "Color:rgb (0, 0, 136); box-sizing:border-box;" >this</span>.<span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); Box-sizing:border-box; " >value</span> = <span class= "Hljs-keyword" style= "Color:rgb (0, 0, 136); Box-sizing:border-box; "
>value</span>; } <span class= "Hljs-keyword" style= "Color:rgb (0, 0, 136); Box-sizing:border-box; " >public</span> observable<string> <span class= "Hljs-title" style= "Box-sizing:border-box"; >valueObservable</span> () {<span class= "Hljs-keyword" style= "Color:rgb (0, 0, 136); Box-sizing:border-box ;" >return</span> observable.just (<span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); Box-sizing: Border-box; "
>value</span>); }}</code><ul class= "pre-numbering" style= "Box-sizing:border-box; Position:absolute; width:50px; top:0px; left:0px; margin:0px; padding:6px 0px 40px; border-right-width:1px; Border-right-style:solid; Border-right-color:rgb (221, 221, 221); List-style:none; Text-align:right; Background-color:rgb (238, 238, 238); ><li style= "Box-sizing:border-box; padding:0px 5px; " >1</li><li style= "Box-sizing:border-box; padding:0px 5px; " >2</li><li style= "Box-sizing:border-box; padding:0px 5px; " >3</li><li style= "Box-sizing:border-box; padding:0px 5px; " >4</li><li style= "Box-sizing:border-box; padding:0px 5px; " >5</li><li style= "Box-sizing:border-box; padding:0px 5px; " >6</li><li style= "Box-sizing:border-box; padding:0px 5px; " >7</li><li style= "Box-sizing:border-box; padding:0px 5px; " >8</li><li style= "Box-sizing:border-box; padding:0px 5px; " >9</li><li style= "Box-sizing:border-box; padding:0px 5px; " >10</li><li style= "BoX-sizing:border-box; padding:0px 5px; " >11</li></ul><ul class= "pre-numbering" style= "Box-sizing:border-box; Position:absolute; width:50px; top:0px; left:0px; margin:0px; padding:6px 0px 40px; border-right-width:1px; Border-right-style:solid; Border-right-color:rgb (221, 221, 221); List-style:none; Text-align:right; Background-color:rgb (238, 238, 238); ><li style= "Box-sizing:border-box; padding:0px 5px; " >1</li><li style= "Box-sizing:border-box; padding:0px 5px; " >2</li><li style= "Box-sizing:border-box; padding:0px 5px; " >3</li><li style= "Box-sizing:border-box; padding:0px 5px; " >4</li><li style= "Box-sizing:border-box; padding:0px 5px; " >5</li><li style= "Box-sizing:border-box; padding:0px 5px; " >6</li><li style= "Box-sizing:border-box; padding:0px 5px; " >7</li><li style= "Box-sizing:border-box; padding:0px 5px; " >8</li><li style= "Box-sizing:border-boX padding:0px 5px; " >9</li><li style= "Box-sizing:border-box; padding:0px 5px; " >10</li><li style= "Box-sizing:border-box; padding:0px 5px; " >11</li></ul>

What will the code print after it is run?

<code class= "HLJS cs has-numbering" style= "Display:block"; padding:0px; Color:inherit; Box-sizing:border-box; font-family: ' Source Code Pro ', monospace;font-size:undefined; White-space:pre; border-radius:0px; Word-wrap:normal; background:transparent; " >sometype instance = <span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); Box-sizing:border-box; "  
>new</span> SomeType (); observable<string> <span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); Box-sizing:border-box; "  
>value</span> = Instance.valueobservable (); Instance.setvalue (<span class= "hljs-string" style= "Color:rgb" (0, 136, 0); box-sizing:border-box; "  
> "Some Value" </span>); <span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); Box-sizing:border-box; " >value</span>.subscribe (System.<span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); Box-sizing: Border-box; " >out</span&gt::p rintln); </code><ul class= "pre-numbering" style= "Box-sizin"G:border-box; Position:absolute; width:50px; top:0px; left:0px; margin:0px; padding:6px 0px 40px; border-right-width:1px; Border-right-style:solid; Border-right-color:rgb (221, 221, 221); List-style:none; Text-align:right; Background-color:rgb (238, 238, 238); ><li style= "Box-sizing:border-box; padding:0px 5px; " >1</li><li style= "Box-sizing:border-box; padding:0px 5px; " >2</li><li style= "Box-sizing:border-box; padding:0px 5px; " >3</li><li style= "Box-sizing:border-box; padding:0px 5px; " >4</li></ul><ul class= "pre-numbering" style= "Box-sizing:border-box; Position:absolute; width:50px; top:0px; left:0px; margin:0px; padding:6px 0px 40px; border-right-width:1px; Border-right-style:solid; Border-right-color:rgb (221, 221, 221); List-style:none; Text-align:right; Background-color:rgb (238, 238, 238); ><li style= "Box-sizing:border-box; padding:0px 5px; " >1</li><li style= "Box-sizing:border-box; padding:0px 5px; " >2</li><li style= "Box-sizing:border-box; padding:0px 5px; " >3</li><li style= "Box-sizing:border-box; padding:0px 5px; " >4</li></ul>

If you think it will print out "Some Value", that's wrong. The actual print result is "null." Because the value is initialized when Observable.just () is invoked.

Just (), from () the ability to create observable operators (Translator Note: Create the observable operator) at the beginning of the creation, has stored the value of the object, and not be subscribed to. This is obviously not an expected performance, and the valueobservable I want () is the current value that can be expressed whenever requested. Self-Help

One solution is to use observable.create () because it allows precise control over the sending of events for each subscriber.

Public observable valueobservable () {
Return Observable.create (New Observable.onsubscribe () {
@Override public void Call (Subscriber simple and rough

Here's a way to implement a custom operator that doesn't need to be customized:

<code class= "HLJS cs has-numbering" style= "Display:block"; padding:0px; Color:inherit; Box-sizing:border-box; font-family: ' Source Code Pro ', monospace;font-size:undefined; White-space:pre; border-radius:0px; Word-wrap:normal; background:transparent; " ><span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); Box-sizing:border-box; " >public</span> observable<string> <span class= "Hljs-title" style= "Box-sizing:border-box"; >valueObservable</span> () {<span class= "Hljs-keyword" style= "Color:rgb (0, 0, 136); Box-sizing:border-box ;" >return</span> Observable.defer (<span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); Box-sizing: Border-box; " >new</span> func0<observable<string>> () {@Override <span class= "Hljs-keyword" style= "color: RGB (0, 0, 136); Box-sizing:border-box; " >public</span> observable<string> <span class= "Hljs-title" style= "Box-sizing:border-box";
>call</span> () {      <span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); Box-sizing:border-box; " >return</span> observable.just (<span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); Box-sizing: Border-box; "
    >value</span>);
}
  }); }</code><ul class= "pre-numbering" style= "Box-sizing:border-box; Position:absolute; width:50px; top:0px; left:0px; margin:0px; padding:6px 0px 40px; border-right-width:1px; Border-right-style:solid; Border-right-color:rgb (221, 221, 221); List-style:none; Text-align:right; Background-color:rgb (238, 238, 238); ><li style= "Box-sizing:border-box; padding:0px 5px; " >1</li><li style= "Box-sizing:border-box; padding:0px 5px; " >2</li><li style= "Box-sizing:border-box; padding:0px 5px; " >3</li><li style= "Box-sizing:border-box; padding:0px 5px; " >4</li><li style= "Box-sizing:border-box; padding:0px 5px; " >5</li><li style= "Box-sizing:border-box; padding:0px 5px;" >6</li><li style= "Box-sizing:border-box; padding:0px 5px; " >7</li></ul><ul class= "pre-numbering" style= "Box-sizing:border-box; Position:absolute; width:50px; top:0px; left:0px; margin:0px; padding:6px 0px 40px; border-right-width:1px; Border-right-style:solid; Border-right-color:rgb (221, 221, 221); List-style:none; Text-align:right; Background-color:rgb (238, 238, 238); ><li style= "Box-sizing:border-box; padding:0px 5px; " >1</li><li style= "Box-sizing:border-box; padding:0px 5px; " >2</li><li style= "Box-sizing:border-box; padding:0px 5px; " >3</li><li style= "Box-sizing:border-box; padding:0px 5px; " >4</li><li style= "Box-sizing:border-box; padding:0px 5px; " >5</li><li style= "Box-sizing:border-box; padding:0px 5px; " >6</li><li style= "Box-sizing:border-box; padding:0px 5px; " >7</li></ul>

All I did was use the defer () operator to encapsulate the original code, but now I'm doing what I want. The code in defer () is not executed until it is subscribed to. We just need to call Observable.just () when the data is requested.

I prefer the reason for this solution:

Simpler than observable.create (), no need to manually invoke OnCompleted ().
Using built-in operators, this approach (and possibly) is more officially affirmed.
The only disadvantage of using the defer () operator is that each subscription creates a new observable object. The Create () operator uses the same function for each subscriber, so the latter is more efficient. As always, if necessary, you can test performance or try to optimize. Deep

The above code is just for the explanation, but to switch to actual production, we need to replace all the code with Behaviorsubject. Let's look at some more complex things.

Suppose you need a method that first writes the data to disk and then returns it as the result. This is an implementation with the defer () operator:

<code class= "HLJS cs has-numbering" style= "Display:block"; padding:0px; Color:inherit; Box-sizing:border-box; font-family: ' Source Code Pro ', monospace;font-size:undefined; White-space:pre; border-radius:0px; Word-wrap:normal; background:transparent; " ><span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); Box-sizing:border-box; " >public</span> observable<sometype> <span class= "Hljs-title" style= "Box-sizing:border-box"; >createSomeType</span> (Final String <span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); Box-sizing: Border-box; " >value</span>) {<span class= "Hljs-keyword" style= "Color:rgb (0, 0, 136); box-sizing:border-box;" >return</span> Observable.defer (<span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); Box-sizing: Border-box; " >new</span> func0<observable<sometype>> () {@Override <span class= "Hljs-keyword" style= " Color:rgb (0, 0, 136); Box-sizing:border-box; " >public</span> observable<sometype> <span class= "Hljs-title" style= "Box-sizing:border-box"; >call</span> () {SomeType SomeType = <span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); Box-sizin G:border-box; "
      >new</span> SomeType (); Sometype.setvalue (<span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); box-sizing:border-box; "

      >value</span>); <span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); Box-sizing:border-box; "
      >try</span> {db.writetodisk (someType); } <span class= "Hljs-keyword" style= "Color:rgb (0, 0, 136); Box-sizing:border-box; " >catch</span> (IOException e) {<span class= "Hljs-keyword" style= "Color:rgb" (0, 0, 136); box-sizing:b Order-box; "
      >return</span> Observable.error (e); } <span class= "Hljs-keyword" style= "Color:rgb (0, 0, 136); Box-sizing:border-box; "
    >return</span> Observable.just (SomeType);
}
  }); }</code><uL class= "pre-numbering" style= "Box-sizing:border-box; Position:absolute; width:50px; top:0px; left:0px; margin:0px; padding:6px 0px 40px; border-right-width:1px; Border-right-style:solid; Border-right-color:rgb (221, 221, 221); List-style:none; Text-align:right; Background-color:rgb (238, 238, 238); ><li style= "Box-sizing:border-box; padding:0px 5px; " >1</li><li style= "Box-sizing:border-box; padding:0px 5px; " >2</li><li style= "Box-sizing:border-box; padding:0px 5px; " >3</li><li style= "Box-sizing:border-box; padding:0px 5px; " >4</li><li style= "Box-sizing:border-box; padding:0px 5px; " >5</li><li style= "Box-sizing:border-box; padding:0px 5px; " >6</li><li style= "Box-sizing:border-box; padding:0px 5px; " >7</li><li style= "Box-sizing:border-box; padding:0px 5px; " >8</li><li style= "Box-sizing:border-box; padding:0px 5px; " >9</li><li style= "Box-sizing:border-box; padding:0px 5px; " >10</li><li style= "Box-sizing:border-box; padding:0px 5px; " >11</li><li style= "Box-sizing:border-box; padding:0px 5px; " >12</li><li style= "Box-sizing:border-box; padding:0px 5px; " >13</li><li style= "Box-sizing:border-box; padding:0px 5px; " >14</li><li style= "Box-sizing:border-box; padding:0px 5px; " >15</li><li style= "Box-sizing:border-box; padding:0px 5px; " >16</li><li style= "Box-sizing:border-box; padding:0px 5px; " >17</li></ul><div class= "Save_code tracking-ad data-mod=" popu_249 "style=" Box-sizing:border-box ; Position:absolute; height:60px; right:30px; top:5px; Color:rgb (255, 255, 255); Cursor:pointer; Z-index:2; " ><a target=_blank target= "_blank" style= "box-sizing:border-box"; Color:rgb (12, 137, 207); ></a>&lt/div><ul class= "pre-numbering" style= "Box-sizing:border-box; Position:absolute; width:50px; top:0px; left:0px; margin:0px; padding:6px 0px 40px; border-right-width:1px; Border-right-style:solid; Border-right-color:rgb (221, 221, 221); List-style:none; Text-align:right; Background-color:rgb (238, 238, 238); ><li style= "Box-sizing:border-box; padding:0px 5px; " >1</li><li style= "Box-sizing:border-box; padding:0px 5px; " >2</li><li style= "Box-sizing:border-box; padding:0px 5px; " >3</li><li style= "Box-sizing:border-box; padding:0px 5px; " >4</li><li style= "Box-sizing:border-box; padding:0px 5px; " >5</li><li style= "Box-sizing:border-box; padding:0px 5px; " >6</li><li style= "Box-sizing:border-box; padding:0px 5px; " >7</li><li style= "Box-sizing:border-box; padding:0px 5px; " >8</li><li style= "Box-sizing:border-box; padding:0px 5px; " >9</li><li style= "Box-siziNg:border-box; padding:0px 5px; " >10</li><li style= "Box-sizing:border-box; padding:0px 5px; " >11</li><li style= "Box-sizing:border-box; padding:0px 5px; " >12</li><li style= "Box-sizing:border-box; padding:0px 5px; " >13</li><li style= "Box-sizing:border-box; padding:0px 5px; " >14</li><li style= "Box-sizing:border-box; padding:0px 5px; " >15</li><li style= "Box-sizing:border-box; padding:0px 5px; " >16</li><li style= "Box-sizing:border-box; padding:0px 5px; " >17</li></ul>

This example is a little more complicated, and if you throw an exception and catch it when you write the data into the disk, call OnError immediately, and the basic idea is the same: you don't want to execute any code until the subscription occurs.

In fact, there are many ways to solve the above problem, although using the defer () operator is only one of them, but it is very convenient to use.

Original link: Deferring observable code until subscription in Rxjava
Original Author: Dan Lew
The Jianshu of Xiao Tang

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.