Redux соединяет цепочки асинхронных действий

Я пытаюсь настроить redux, react-redux и redux-thunk. Мысли в целом идут хорошо, но у меня есть вопрос о том, как все должно выглядеть при объединении нескольких асинхронных действий вместе.

В частности, у меня есть сценарий, в котором действия могут быть вызваны индивидуально или косвенно другим действием, которое может их вызывать. Мой вопрос в том, как следует писать selectItem, если я хочу быть идиоматичным?

action.js

export function fetchByContext(contextId) { 
    return dispatch => {
        _fetchByContext(messages => { 
            dispatch({ type: RECEIVE_MESSAGES, ... });
        });
    };
};

export function subscribeByContext(contextId) {
    return dispatch => {
        _subscribeByContext(messages => { 
            dispatch({ type: RECEIVE_MESSAGES, ... });
        });
    };
};

export function selectItem(contextId) {
    return dispatch => {
        subscribeByContext(contextId)(dispatch);
        fetchByContext(contextId)(dispatch);
    };
};

person anthonyv    schedule 30.05.2016    source источник
comment
асинхронно, ожидайте ключевой работы, может быть, это поможет   -  person gu mingfeng    schedule 30.05.2016


Ответы (1)


Я считаю, что ключ в том, что (ref):

Любое возвращаемое значение из внутренней функции будет доступно как возвращаемое значение самой отправки.

Если внутренние функции fetchByContext(), subscribeByContext() возвращают обещание, они могут быть связаны последовательно или выполняться параллельно из selectItem(). Непроверенная реализация, предполагающая, что ни _fetchByContext(), ни _subscribeByContext() не возвращают обещание, будет:

export function fetchByContext(contextId) { 
    return dispatch => {
        return new Promise((resolve, reject) => {
            _fetchByContext(messages => { 
                dispatch({ type: RECEIVE_MESSAGES, ... });
                resolve(messages);
            });
        });
    };
};

export function subscribeByContext(contextId) {
    return dispatch => {
        return new Promise((resolve, reject) => {
            _subscribeByContext(messages => { 
                dispatch({ type: RECEIVE_MESSAGES, ... });
                resolve(messages);
            });
        });
    };
};

export function selectItem(contextId) {
    return dispatch => {
        // CALL IN SERIES
        return dispatch(subscribeByContext(contextId))
            .then(() => dispatch(fetchByContext(contextId)));
        // CALL IN PARALLEL (alternative to the code above; this is probably not what you want - just keeping for reference)
        return Promise.all(
            dispatch(subscribeByContext(contextId)),
            dispatch(fetchByContext(contextId))
        );
    };
}

Еще раз обратите внимание, что приведенный выше код не тестировался, просто в надежде дать представление об общем решении.

person Nikos Paraskevopoulos    schedule 30.05.2016