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.