Сделайте вызовы преобразователя Redux синхронными для обновления токенов

Интегрированный редукс с промежуточным программным обеспечением thunk. По истечении срока действия токена доступа вызывается API-интерфейс обновления токена, и в случае его успеха снова вызывается первый API-интерфейс, который не был успешным из-за просроченного токена.

API токена обновления вызывается и возвращается, поскольку он асинхронный. и API редактирования вызывается сразу перед ответом об успешном обновлении токена. Как сделать его синхронным, чтобы вызывать API только после получения ответа токена обновления

export function editClothDetails(data, id) {
return  function(dispatch, getState) {
    dispatch({ type: actions.EDIT_CLOTH_REQUEST });
     fetch(BASE_URL + EDIT_CLOTH_URL + `/${id}`, {
        method: "PUT",
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            'Authorization': 'Bearer ' + getState().Auth.accessToken
        },
        body: JSON.stringify({ ...data })
    })
    .then(result => checkHttpStatus(result))
    .then(result => checkForError(result))
    .then(jsonResponse => {
        dispatch({
            type: actions.EDIT_CLOTH_SUCCESS,
            payload: jsonResponse
        });
    })
    .catch((error) => {
        if(error.message === "Invalid token") {
            //what should be the right way to make these dispatches synchronous
            dispatch(refreshToken());
            dispatch(editClothDetails(data, id)); //setTimeout(()=> dispatch(editClothDetails(data, id)), 100);
        }
        console.error("There is an error in editing cloth details !! " + error.message);
        dispatch({
            type: actions.EDIT_CLOTH_FAILED,
            payload: error.message
        });
    });
};
}

export function refreshToken() {
    return (dispatch, getState) => {
        dispatch({ type: actions.REFRESH_TOKEN_REQUEST });
        fetch(BASE_URL + '/token', {
            method: "GET",
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'authorization': 'Bearer ' + getState().Auth.refreshToken
            },
        })
        .then(result => checkHttpStatus(result))
        .then(result => checkForError(result))
        .then(jsonResponse => {
            storeLocally(constants.APP_NAME, jsonResponse);
            dispatch({
                type: actions.REFRESH_TOKEN_REQUEST_SUCCESS,
                payload: jsonResponse
            });
        })
        .catch((err) => {
            console.error("There is an error refreshing token !!" + err.message);
            dispatch({
                type: actions.REFRESH_TOKEN_REQUEST_FAILED,
                payload: err.message
            });
        });
    };
}

person Sachin Nayak    schedule 21.09.2020    source источник


Ответы (1)


Вы должны использовать async-await здесь...

export function editClothDetails(data, id) {
return  async function(dispatch, getState) {      // -> see here

    .catch((error) => {
        if(error.message === "Invalid token") {
            await dispatch(refreshToken());                 //--> see here
            dispatch(editClothDetails(data, id)); 
        }
 
 // your other code
      
};
}

export async function refreshToken() {.  /// ---> see here
    return async (dispatch, getState) => {
        dispatch({ type: actions.REFRESH_TOKEN_REQUEST });
        /// your other code
    };
}
person Mohammad Faisal    schedule 21.09.2020
comment
Выдает ошибку, говорящую, что await находится вне функции - person Sachin Nayak; 22.09.2020
comment
если вы можете создать песочницу, я могу проверить ее для вас - person Mohammad Faisal; 22.09.2020