Java響應式編程之handle用法解析
Java handle用法
JAVA響應式編程reactor中如果需要對一個flux中的數據進行提前返回 可以使用handle
具體如下:
@GetMapping("/a") public Mono<Object> a() throws InterruptedException { long begin = System.currentTimeMillis(); Mono<String> m5 = Mono.just("").map(s -> { try { TimeUnit.SECONDS.sleep(5); System.out.println("5"); System.out.println(System.currentTimeMillis() - begin); } catch (InterruptedException e) { e.printStackTrace(); } return "5"; }).subscribeOn(Schedulers.boundedElastic()); Mono<String> m8 = Mono.just("").map(s -> { try { TimeUnit.SECONDS.sleep(8); System.out.println("8"); System.out.println(System.currentTimeMillis() - begin); } catch (InterruptedException e) { e.printStackTrace(); } return "8"; }).subscribeOn(Schedulers.boundedElastic()); Mono<String> m10 = Mono.just("").map(s -> { try { TimeUnit.SECONDS.sleep(15); System.out.println("15"); System.out.println(System.currentTimeMillis() - begin); } catch (Exception e) { e.printStackTrace(); } return "15"; }).subscribeOn(Schedulers.boundedElastic()); Mono<Object> single = Flux.merge(m8, m5, m10).handle(((s, synchronousSink) -> { if ("8".equals(s)) { synchronousSink.next("盧本偉牛"); synchronousSink.complete(); } })).defaultIfEmpty("null").single(); return single; }
subscribeOn(Schedulers.boundedElastic())是讓這些mono進行異步處理
上述定義了3個Mono進行請求 使用Sleep進行模擬請求中業(yè)務處理耗時
m5是需要執(zhí)行3s m8是需要執(zhí)行8s m10是需要執(zhí)行15s
如果我們有多個耗時處理的請求 需要同時請求 然后又需要合并結果 并且返回我們需要的結果 進行提前返回。
例如:我需要同時請求這些接口 當8這個接口有結果返回的時候 由于其他請求時間太長了 需要提前返回一個值 放棄其他結果處理 所以我們可以進行判斷.
//這個s代表前面?zhèn)魅氲脑?執(zhí)行完會傳入這個handle // synchronousSink.next() 代表我執(zhí)行完這個流返回給下一個進行處理 next(Object) // synchronousSink.complete(); 代表我們執(zhí)行完取消其他的流 Flux.merge(m8, m5, m10).handle(((s, synchronousSink) -> { if ("8".equals(s)) { synchronousSink.next("盧本偉牛"); synchronousSink.complete(); } })).subscribe(s -> { System.err.println(s); });
由于上面當s為8的時候 將盧本偉牛傳入下一個流 然后執(zhí)行完成 所以還有個m10不會執(zhí)行完 就會直接丟棄
我們進行測試
發(fā)現控制臺打印
我們如果使用傳統的mvc執(zhí)行m5我們會耗時5s m8會耗時8s 加起來就是13s
我們使用響應式編程則只會耗時8s 當如果多個耗時操作拼接在一起 我們需要多個返回結果的時候我們可以使用handle進行提前返回
返回結果為盧本偉牛 也就是我們之前當s為8時執(zhí)行的 ,synchronousSink.next(“盧本偉牛”);,將這個字符串傳給最終結果的流,當然我們也可以根據自己的邏輯 發(fā)放多個synchronousSink.next。
handle的標準使用方式
在Java語言中,直接將handle聲明為Activity的內部類去使用handle,非靜態(tài)內部類會持有外部類的一個隱試引用,這樣就可能造成外部類無法被垃圾回收,從而導致內存泄漏。
故而,給出規(guī)范的handle使用方式如下:
handle的基類
public class UIHandler<T> extends Handler{ ? ? ? ?protected WeakReference<T> ref; ? ? ? ?public UIHandler(T cla){ ? ? ? ? ref = new WeakReference<T>(cla); ? ? ?} ? ? ? ? public T getRef(){ ? ? ? ? ? return ref != null ? ref.get() : null; ? ? ? } }
handle運用實例
public class MainActivity extends Activity{ ? ? ? private final MainHandler mHandler = new MainHandler(this); ? ? ? @Override ? ? protected void onCreate(Bundle savedInstanceState){ ? ? ? ? super.oncreate(savedInstanceState); ? ? ? ? setContentView(R.layout.activity_main); ? ? ? ? mHandler.post(mRunnable); ? ? } ? ? ? private static final Runnable mRunnable = new Runnable(){ ? ? ? ? ? @Override ? ? ? ? ?public void run(){ ? ? ? ? ? ?} ? ? }; ? ? ? private class MainHandler extends UIHandler{ ? ? ? ? ?private MainHandler(MainActivity activity){ ? ? ? ? ? ? ?super(activity); ? ? ? ? ?} ? ? ? ? ? ? ? ? ? ?@Override ? ? ? ? ?public void handleMessage(Message msg){ ? ? ? ? ? ? ?super.handleMessage(msg); ? ? ? ? ? ? ?MainActivity activity = (MainActivity)ref.get(); ? ? ? ? ? ? ?if(activity != null){ ? ? ? ? ? ? ? ? if (activity.isFinishing() ? ? ? ? ? ? ? ? ? ? return; switch(msg.what){ case 1: break; } ? ? ? ? ? ? ?} ? ? ? ? ?} ? ? } } ? ?
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Netty分布式pipeline管道創(chuàng)建方法跟蹤解析
這篇文章主要為大家介紹了Netty分布式pipeline管道創(chuàng)建方法跟蹤解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-03-03