2017-08-03 159 views
0

我是REDX-SAGO的小菜,如果我錯過了一些明顯的東西,請耐心等待。如何確保一個佐賀完成之前完成?

我有一個場景,我使用的是REDX-SAGA從OIDC提供程序中獲取access_token並將其存儲在瀏覽器的localStorage中。 我也使用Sagas從API端點獲取一些數據。 但是我一直在使用這種方法遇到問題,因爲調用外部API的Saga在Auth Saga可以使用access_token解析之前被調用。

我的驗證城:

export function * handleFetchTokens() { 
    try { 
    const token = yield cps(getToken) 
    localStorage.setItem('token', token) 
    const isAuthenticated = !!(token) 
    yield put(actions.checkAuthSuccess(isAuthenticated)) 
    } catch (e) { 
    yield put(actions.checkAuthFailure(e)) 
    } 
} 
export default function * sagas() { 
    yield fork(takeLatest, actions.CHECK_AUTH, handleFetchTokens) 
} 

我的API城:

export function * handleFetchItems() { 
    try { 
    const response = yield call(getItems) 
    yield put(actions.fetchItemsSuccess(response)) 
    } catch (e) { 
    yield put(actions.fetchItemsFailure(e.errors)) 
    } 
} 
export default function * sagas() { 
    yield fork(takeLatest, actions.FETCH_ITEMS, handleFetchItems) 
} 

我的根之城:

export default function * root() { 
    yield fork(items.sagas) 
    yield fork(authentication.sagas) 
} 

應該怎樣解決這個問題的正確方法?

回答

0

個人而言,我會確保在允許我的應用程序的任何部分實際調用FETCH_ITEMS操作之前收到令牌。假設你不想引入這樣的邏輯,你必須在獲得令牌之前決定如何處理FETCH_ITEMS操作。

最簡單的方法是忽略它們,但這也可能不是最可行的方法。

所以剩下的就是緩衝FETCH_ITEMS操作。你可以使用actionChannel來做到這一點。由於您使用takeLatest您還需要定義大小的滑動緩存1.

它可能看起來ruffly這樣的:

export default function * sagas() { 
    const chan = yield actionChannel(actions.FETCH_ITEMS, buffers.sliding(1)) 
    yield take('TOKEN_RECEIVED') // wait for action informing us token was received 
    chan.close() 
    yield fork(takeLatest, chan, handleFetchItems) 
    yield fork(takeLatest, actions.FETCH_ITEMS, handleFetchItems) 
} 

更多actionChannels這裏https://redux-saga.js.org/docs/advanced/Channels.html


另一種方法 - 寫少一點,但也少一點控制 - 而不是緩衝是等待在取材傳奇本身:

export function * handleFetchItems() { 
    while (!token) yield take('TOKEN_RECEIVED'); 
    ... 
} 

無論哪種方式,兩種方式都依賴於等待收到令牌後需要調度的TOKEN_RECEIVED操作。

+0

儘管我仍然在努力完成這項工作,但您的建議似乎相當不錯。我想知道我是否可以實現類似於您所說的「在從應用中分派任何操作之前獲取令牌」。這聽起來好多了! 基本上,我派遣了在'react-router's'onEnter'上獲取令牌的動作,並且由於傳奇的異步性質,處理需要使用該令牌的所有其他動作變得非常棘手。 – Hawkes

+0

也許,在應用程序的開始階段(呈現應用程序/路由器之前),您可以渲染簡單的加載器並請求令牌。一旦你收到令牌,你可以渲染整個應用程序,包括反應路由器。這樣就不會有任何視圖邏輯可以在調用可用之前調用任何需要令牌的其他操作。 –

相關問題