How to Build a Wheel with android Flow Flow Response

  • 2021-11-14 07:10:51
  • OfStack

Click on me, the code is here

Cause

In code code, we often encounter asynchronous method nesting. For example, after submitting the file, submit the form, submit the data according to whether it is successful or not, and then make other logical processing. kotlin puts forward the concept of synergy, and uses grammar sugar to solve this problem. There is also async/await in javaScript to make asynchronous work like synchronization. In java, I haven't found this feature for the time being, which makes writing asynchronous nesting feel like hell, like eating shit 1. Taking advantage of this Spring Festival, I tried to solve this problem according to my own ideas and build a flowing wheel, so I wrote Flow frame.

Thoughts

Thinking about codes from life, the principle of nesting methods and water flow is very similar. We regard each asynchronous as a water pipe, and water flows through each pipe, and each pipe can process and convert water. This process of transformation is regarded as an event Event. In the wrapper event, we can perform a series of transformations, such as thread transformation, event transformation, merge and split, etc. If an exception is encountered, the stream is terminated directly.

Function

Simple use

Create a stream through the Flow static create method, and then concatenates the next stream, if you do not need to return the Void generic. Event has two generic P, R, the first is the return value type of the previous stream Flow, and the second is the return type of the current stream Flow. The await exec method ends the current stream of events and substitutes the result into the next stream.

Print two sentences


Flow.create(new Event<Void,Void>() {
          @Override
          public void run(Flow flow, Void aVoid, Await<Void> await) {
            System.out.println("this is first flow");
            await.exec(null);
          }
          
        }).then(new Event<Void, Void>() {
          @Override
          public void run(Flow flow, Void aVoid, Await<Void> await) {
            System.out.println("this is two flow");
            await.exec(null); 
          }
        }).start();

After simplification of Lambda,


Flow.create((NoneEvent) (flow, await) -> {
          System.out.println("this is first flow");
          await.exec(); 
        }).then((NoneEvent) (flow, await) -> {
            System.out.println("this is two flow");
            await.exec();
        }).start();

Addition of two numbers


 Flow.create((FirstEvent<Integer>) (flow, await) -> 
            await.exec(3))
           .then((Event<Integer, Integer>) (flow, integer, await) -> 
               await.exec(integer + 5))
           .resultThen((flow, result) -> 
               System.out.println("total is"+result))
           .start();

The resultThen method returns the result of the current stream, and the result of the stream can be obtained by using resultThen after each flow. If an exception is encountered, it can be thrown through the flow throwException method, which can be handled immediately after flow, or at the end of flow catchThen. finallyThen is a notification of the end of the event stream.


 Flow.create((FirstEvent<Integer>) (flow, await) ->
            await.exec(0))
           .then((Event<Integer, Integer>) (flow, perVal, await) ->{
             if(perVal == 0){
               flow.throwException("Dividend cannot be 0!");
             }else{
               await.exec(perVal/5);
             }
           })
           .resultThen((flow, result) ->
               System.out.println("total is"+result))
           .catchThen((flow, e) ->
               System.out.println(e.getMessage()))
            .finallyThen((flow, await) -> 
               System.out.println("this is flow end")).start();

Switch threads

Threads can be switched using the flow on method, and on passes an Converter parameter to represent the next stream switch. If two Converter parameters, it means that both the current stream and the next stream switch threads. Of course, you can also implement Converter interface to realize other functions.


Flow.create((FirstEvent<Integer>) (flow, await) ->
            await.exec(0))
           .on(AndroidMain.get(),SingleThread.get())  
           .then((Event<Integer, Integer>) (flow, perVal, await) ->{
             if(perVal == 0){
               flow.throwException("Dividend cannot be 0!");
             }else{
               await.exec(perVal/5);
             }
           })
           .on(AndroidMain.get())
           .resultThen((flow, result) ->
               System.out.println("total is"+result))
           .on(AndroidMain.get())
           .catchThen((flow, e) ->
               System.out.println(e.getMessage()))
           .on(SingleThread.get())
           .finallyThen((flow, await) ->
               System.out.println("this is flow end")).start();

Collection results are converted to multiple streams


Flow.each((FirstEvent<List<String>>) (flow, await) -> {
          ArrayList<String> list = new ArrayList<>();
          list.add("1");
          list.add("2");
          list.add("3");
          await.exec(list);
        }).then((LastEvent<String>) (flow, s, await) -> {
          System.out.println("this is"+s);
        }).start();

Multiple stream results are converted to one stream


 Flow.merge((flow, await) -> await.exec(1),
            (flow, await) -> await.exec(2),
            (flow, await) -> await.exec(2)).resultThen((flow, result)
            -> System.out.println"result"+result)).start();

Conditional selection

Re-initiate Flow stream according to condition judgment (return parameter may not be 1 sample)


 Flow.create((NoneEvent) (flow,await) ->{
          System.out.println("start");
          await.exec();
        })
         .on(SingleThread.get())
         .conditionThen((VoidCondition) () -> false,
                Flow.create((NoneEvent) (flow,await) -> {
                  System.out.println("this is true");
                  await.exec();
                }),
                Flow.create((NoneEvent) (flow,await) -> {
                  System.out.println("this is false");
                  await.exec();
                })).start();

According to the condition judgment, Flow flow can be merged into 1. (Return parameter must be 1)


Flow.condition2(() -> isGo, (FirstEvent<Integer>) (flow, await) -> {
          System.out.println("this is true");
          await.exec(1);
        }, (flow, await) -> {
          System.out.println("this is false");
          await.exec(0);
        }).resultThen((flow, result) -> System.out.println("result"+result))
            .watch(this).start();

Lifecycle unbinding

By flow watch method. Observers must implement the ILifeObservable interface.


 Flow.create((FirstEvent<Integer>) (flow, await) ->await.exec(0)) 
   .watch(this).start();

Summarize

The frame also provides some simplified classes, and can also abstract its own Event with the project network request framework, so it is almost the same as then of the network of js. Follow-up adjustment according to actual needs, in the test.


Related articles: