首页 > 解决方案 > 跨 redux sagas 同步令牌获取的最佳方法

问题描述

因此,我希望能够在所有命中特定 API 的 sagas 中使用一个通用函数来获取令牌。这就是我想出的

function* getValidAuthToken(params: TokenParams) {
    // Refresh token 5 seconds before actual expiration. This gives some buffer time
    // for inflight requests to succeed
    const bufferTimeMS = 10000;

    const token = yield select(tokenSelector);
    if (token && Date.now() < token.tokenExpirationTimeStampMs - bufferTimeMS) {
        return token.tokenValue;
    }


    const isUpdating = yield select(isCurrUpdatingToken);
    // If another saga has already started the process to fetch a new token we just wait for that to finish
    if (isUpdating) {
        yield take(finishTokenUpdate);
        const token = yield select(tokenSelector);
        return token.tokenValue;
    }

    // Else we start the process to get a new lrs token
    yield put(startTokenUpdate());
    const result = yield sdk.getToken(params);
    const { tokenValue, lifetimeSeconds } = result.token;
    const tokenExpirationTimeStamp = Date.now() + lifetimeSeconds * 1000;
    yield put(finishTokenUpdate({ tokenExpirationTimeStampMs: tokenExpirationTimeStamp, tokenValue }));
    return tokenValue;
}

isUpdating如果另一个消费者已经开始了这个过程,我包括了一个状态以避免获取令牌。在这种情况下,我只想等待令牌更新完成,然后获取结果。

但是我注意到在应用程序启动时......多个消费者同时调用我的服务。在这种情况下,isUpdating标志没有时间改变,实际上它的比赛条件天气或不getToken被多次调用。

标签: reactjsreduxredux-saga

解决方案


好吧,实际上我觉得自己很愚蠢......我发布这个的那一刻我发现了我的错误。

我的减速器是这样写的

import { finishTokenUpdate, startTokenUpdate } from './actions';
const isUpdatingTokenHanlder = handleActions(
    {
        startTokenupdate: (state, action) => true,
        finishTokenUpdate: (state, action) => false,
    },
    false,
);

这没有正确定义我的操作键。相反,它应该是

const isUpdatingTokenHanlder = handleActions(
    {
        [`${startTokenUpdate}`]: (state, action) => true,
      ....
);

推荐阅读