Redux connect 链接异步操作

Redux connect chaining async actions

我正在尝试设置 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);
    };
};

我认为关键在于 (ref):

Any return value from the inner function will be available as the return value of dispatch itself

如果 fetchByContext()subscribeByContext() return 的内部函数是一个 promise,则这些可以串联链接或 运行 与 selectItem() 并行链接。一个未经测试的实现,假设既没有 _fetchByContext() 也没有 _subscribeByContext() return 承诺将是:

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

再次请注意,上面的代码未经测试,只是希望为一般解决方案提供一个想法。