2017-08-03 77 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

也许,在应用程序的开始阶段(呈现应用程序/路由器之前),您可以渲染简单的加载器并请求令牌。一旦你收到令牌,你可以渲染整个应用程序,包括反应路由器。这样就不会有任何视图逻辑可以在调用可用之前调用任何需要令牌的其他操作。 –

相关问题