2017-08-07 30 views
4

我有一個用例,在我使用Redux Observables發送另一個動作之前,需要等待一系列動作。我已經看到了一些類似的問題,但我無法理解如何使用這些方法來處理我的給定用例。用Redux Observable等待動作序列

在本質上我想要做的事,像這樣:

action$ 
    .ofType(PAGINATION_CLICKED) // This action occurred. 
    .ofType(FETCH_SUCCESS) // Then this action occurred after. 
    .map(() => analyticsAction()); // Dispatch analytics. 

我也想取消,並啓動序列在類型FETCH_ERROR火災例如,如果再另一個動作。

回答

7

偉大的問題。重要的一點是,action$是一個熱點/多播流的所有行動,因爲他們被派遣(這是一個主題)。由於天氣熱,我們可以多次組合,他們都會聽同樣的動作。

// uses switchMap so if another PAGINATION_CLICKED comes in 
// before FETCH_SUCCESS we start over 

action$ 
    .ofType(PAGINATION_CLICKED) 
    .switchMap(() => 
    action$.ofType(FETCH_SUCCESS) 
     .take(1) // <-------------------- very important! 
     .map(() => analyticsAction()) 
     .takeUntil(action$.ofType(FETCH_ERROR)) 
); 

所以每次我們收到PAGINATION_CLICKED,我們將開始聽監聽一個FETCH_SUCCESS內心的可觀測鏈。擁有那個.take(1)是很重要的,否則我們會繼續傾聽多於一個的FETCH_SUCCESS這可能會導致奇怪的錯誤,即使不是,通常也只是採取您所需要的最佳做法。

如果我們先收到FETCH_ERROR,我們使用takeUntil取消等待FETCH_SUCCESS


作爲獎勵,如果你決定要還做基於錯誤一些分析的東西太多,不僅重新開始,你可以使用兩個流之間race確乎比賽。第一個排出,勝利;另一個是取消訂閱。

action$ 
    .ofType(PAGINATION_CLICKED) 
    .switchMap(() => 
    Observable.race(
     action$.ofType(FETCH_SUCCESS) 
     .take(1) 
     .map(() => analyticsAction()), 
     action$.ofType(FETCH_ERROR) 
     .take(1) 
     .map(() => someOtherAnalyticsAction()) 
    ) 
); 

這是同樣的事情,但使用race爲實例操盤的靜態的。這是您可以選擇的一種風格偏好。他們都做同樣的事情。使用哪一個更清楚你。

action$ 
    .ofType(PAGINATION_CLICKED) 
    .switchMap(() => 
    action$.ofType(FETCH_SUCCESS) 
     .map(() => analyticsAction()) 
     .race(
     action$.ofType(FETCH_ERROR) 
      .map(() => someOtherAnalyticsAction()) 
    ) 
     .take(1) 
); 
+0

我快到了!我結束了你的第一個例子,但沒有(現在明顯的批評)'take(1)'。這基本上意味着「序列」在第一個「PAGINATION_CLICKED」後被忽略。非常感謝,對圖書館的大力支持:) –

+1

不客氣!乾杯。 – jayphelps

相關問題