在 Reactor 中,transform
和 transformDeferred
是兩個用于代碼復用和操作符鏈封裝的高級操作符。它們允許你將一組操作符封裝成一個函數,并在適當的時候應用到響應式流中。以下是它們的詳細總結:
1. transform
操作符
- 作用:
transform
操作符允許你將操作符鏈的一部分封裝成一個函數,并在實例化時(assembly time)應用到原始操作符鏈上。這意味著所有訂閱者都會應用相同的操作符鏈。 - 適用場景:適用于所有訂閱者共享相同行為的場景,例如統一的日志記錄、轉換等。
- 示例:
執行結果如下// 定義一個函數,用于過濾掉"orange"顏色并將其余顏色轉換為大寫Function<Flux<String>, Flux<String>> filterAndMap =f -> f.filter(color -> !color.equals("orange")).map(String::toUpperCase);// 從列表創建Flux,并在過濾和映射前打印每個元素Flux.fromIterable(Arrays.asList("blue", "green", "orange", "purple")).doOnNext(System.out::println)// 使用之前定義的函數對Flux進行轉換.transform(filterAndMap)// 訂閱轉換后的Flux,并打印每個元素.subscribe(d -> System.out.println("Subscriber to Transformed MapAndFilter: " + d));
blue Subscriber to Transformed MapAndFilter: BLUE green Subscriber to Transformed MapAndFilter: GREEN orange purple Subscriber to Transformed MapAndFilter: PURPLE
2. transformDeferred
操作符
- 作用:
transformDeferred
操作符與transform
類似,也允許你將操作符鏈封裝成一個函數,但主要的區別在于函數的執行時機:transformDeferred
是在訂閱發生時(subscription time)才應用函數的。這意味著它可以為每個訂閱者生成不同的操作鏈,甚至可以維護一些狀態(例如計數器、隨機數等)。 - 適用場景:適用于每個訂閱者需要不同操作鏈的場景,例如根據訂閱者的身份、時間、狀態等動態生成不同的操作鏈。
- 示例:
執行結果如下// 使用AtomicInteger來實現線程安全的計數器AtomicInteger ai = new AtomicInteger();// 定義一個函數,根據計數器的值來選擇不同的處理邏輯Function<Flux<String>, Flux<String>> filterAndMap = f -> {// 如果計數器的值為1,則過濾掉"orange"顏色,否則過濾掉"purple"顏色if (ai.incrementAndGet() == 1) {return f.filter(color -> !color.equals("orange")).map(String::toUpperCase);}return f.filter(color -> !color.equals("purple")).map(String::toUpperCase);};// 創建一個Flux,從顏色列表開始,通過.doOnNext()打印每個元素,然后通過.transformDeferred()應用filterAndMap函數Flux<String> composedFlux =Flux.fromIterable(Arrays.asList("blue", "green", "orange", "purple")).doOnNext(System.out::println).transformDeferred(filterAndMap);// 訂閱第一個處理流程的結果composedFlux.subscribe(d -> System.out.println("Subscriber 1 to Composed MapAndFilter :" + d));// 訂閱第二個處理流程的結果composedFlux.subscribe(d -> System.out.println("Subscriber 2 to Composed MapAndFilter: " + d));
blue Subscriber 1 to Composed MapAndFilter :BLUE green Subscriber 1 to Composed MapAndFilter :GREEN orange purple Subscriber 1 to Composed MapAndFilter :PURPLE blue Subscriber 2 to Composed MapAndFilter: BLUE green Subscriber 2 to Composed MapAndFilter: GREEN orange Subscriber 2 to Composed MapAndFilter: ORANGE purple
3. transform
與 transformDeferred
的區別
操作符 | 執行時機 | 是否為每個訂閱者生成不同操作鏈 | 是否可以維護狀態 |
---|---|---|---|
transform | 實例化時 | 否 | 否 |
transformDeferred | 訂閱時 | 是 | 是 |
4. 總結
transform
:適用于所有訂閱者共享相同操作鏈的場景,例如統一的日志記錄、轉換等。transformDeferred
:適用于每個訂閱者需要不同操作鏈的場景,例如根據訂閱者的身份、時間、狀態等動態生成不同的操作鏈。
通過使用 transform
和 transformDeferred
,你可以更靈活地測試響應式流,尤其是當你需要模擬復雜或非標準的數據流時,它們是非常有用的工具。