链接Thunk和Promise中间件的承诺

时间:2016-12-12 13:25:30

标签: javascript reactjs redux promise redux-thunk

我正在使用这样的redux-promise-middlewareredux-thunk

import { applyMiddleware, compose, createStore } from 'redux'

import thunk from 'redux-thunk';
import promise from 'redux-promise-middleware'
import logger from 'redux-logger'

import reducer from './reducers'

const middleware = applyMiddleware(thunk, promise(), logger({diff: true}));
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const enhancer = composeEnhancers(middleware);

export default createStore(
    reducer,
    enhancer)

所以,我想做的是将两个承诺链接在一起。 redux-promise-middleware文档建议使用Promise.all,如下所示:

export function startTest(test) {
    return dispatch => {
        return dispatch({
            type: START_TEST,
            id: test,
            payload: Promise.all([
                dispatch(axios.post(urlJoin(config.portalUrl, 'account/login')))
            ])
        })
    };
}

但是,当我将其发送到商店时,我收到以下错误:

  

错误:操作必须是普通对象。使用自定义中间件进行异步操作。

我配置错误了什么?

2 个答案:

答案 0 :(得分:1)

我想出了这个问题。它需要改为这样的东西:

export function startTest(test) {
    return dispatch => {
        return dispatch({
            type: START_TEST_THUNK,
            payload: Promise.all([
                dispatch({
                    type: START_TEST,
                    payload: axios.post(urlJoin(config.portalUrl, 'account/login')),
                    meta: {
                        id: test
                    }
                })
            ])
        })
    };
}

答案 1 :(得分:0)

这不是您问题的直接答案,但您实际上并不需要使用redux-promise-middleware包。您可以简单地创建自己的中间件来处理承诺。这是我对Promise Middleware的简单实现:

export default function PromiseMiddleware() {
   return (next) => (action) => {
      const {promise, type, ...rest} = action

      if (!promise) return next(action)

      const REQUEST = type + '_REQUEST'
      const SUCCESS = type + '_SUCCESS'
      const FAILURE = type + '_FAILURE'

      next({...rest, type: REQUEST})

      return promise
         .then(result => {

            next({...rest, result, type: SUCCESS})

            return true
         })
         .catch(error => {
            if (DEBUG) {
               console.error(error)
               console.log(error.stack)
            }
            next({...rest, error, type: FAILURE})

            return false
         })
   }
}

你可以像你一样完全应用它:

const middleware = applyMiddleware(thunk, PromiseMiddleware, logger({diff: true}))