2017-08-03 11 views
0

私はredux-sagasでnoobですので、私が明白な何かを忘れてしまったら、私に負担してください!1つの佐賀が他のものの前に完了することを確認する方法?

私はredux-sagaを使用して、OIDCプロバイダからaccess_tokenを取得し、ブラウザのlocalStorageに格納するシナリオを持っています。 私はまた、Sagasを使用してAPIエンドポイントからデータを取得します。 しかし、Auth Sagaがaccess_tokenで解決できるようになる前に、外部APIを呼び出すSagaが呼び出されるため、このアプローチで問題が発生しています。

マイ認証サーガ

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を使用してこれを行うことができます。ここactionChannels https://redux-saga.js.org/docs/advanced/Channels.html


について

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) 
} 

もっと別のアプローチ:あなたはまた、サイズ1

のスライディングバッファを定義したいと思うでしょうtakeLatestを使用しているので、それはこのようにrufflyを見ることができますバッファリングの代わりに、読み込みサガ自体を待つだけです。

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

どちらの方法でも、どちらの方法でも、トークンを受け取った後にディスパッチする必要のあるTOKEN_RECEIVEDアクションを待つことに依存します。

+0

私はまだこの仕事をするのに苦労していますが、あなたの提案はかなり良いようです。私はあなたが言ったことに似た何かを実装できるかどうか疑問に思っていました: 'アクションがアプリケーションから送られる前にトークンを取得する'。これはもっとよく聞こえるよ! 基本的には、 'react-router'の' onEnter'にトークンをフェッチするアクションをディスパッチします。また、sagasの非同期性により、このトークンを使用する必要がある他のすべてのアクションを処理するのはかなり難しいものになります。 – Hawkes

+0

おそらく、アプリケーションの開始時(アプリケーション/ルータをレンダリングする前)に単純なローダーをレンダリングしてトークンを要求するだけかもしれません。トークンを受け取ると、反応ルータを含むアプリケーション全体をレンダリングできます。このようにして、使用可能になる前にトークンを必要とする他のアクションを呼び出すことができるビューロジックは存在しなくなります。 –

関連する問題