Redux学习笔记--异步Action和Middleware

异步Actionjavascript

以前介绍的都是同步操做,Redux经过分发action处理state,全部的数据流都是同步的,若是须要一步的话怎么办?java

最简单的方式就是使用同步的方式来异步,将原来同步时一个action拆分红多个异步的action的,在异步开始前、异步请求中、异步正常返回(异常)操做分别使用同步的操做,从而模拟出一个异步操做了。es6

固然,这样的方式是比较麻烦的,如今已经有redux-saga等插件来解决这些问题了。。web

Middlewarespring

Middleware提供的是位于 action 被发起以后,到达 reducer 以前的扩展点。在每次分发action时,全部的Middleware都会执行。编程

Middleware相似spring中的面向切面编程的思想。本质上是注册一系列的操做,在分发action以前链式执行操做。redux

理解Middlewareapp

尝试来解读一下middleware的实现原理。以记录日志为例,咱们来一步步分析Middleware的操做。异步

  1. 首先咱们能想到的就是在dispatch action的代码先后加上log的代码,可是这样的话须要在全部的dispatach语句先后加代码,太麻烦。
  2. 那么咱们是否是能够封装dispatch方法,将log的代码加到封装的方法里面去。可是这种状况下须要针对每一个action都封装不一样的方法来完成。
  3. 咱们也能够直接替换dispatch方法,用咱们本身封装的方法来代替dispatch。这样能够解决问题,可是新的问题又出来了,假如咱们在dispatch前出了log还须要作其余操做怎么办?继续去丰富咱们替换的方法?好像不太合适。。。
  4. 把dispatch方法当作参数

在上面的步骤三中,咱们把原生dispat方法替换了,从而无法添加多个处理操做。那么咱们是否能够把dispatch函数当成是参数,在每一个处理操做函数中,除了正常的操做流程外,可使用dispatch参数,最终仍然将此参数返回。函数

function logger(store) {
  return function wrapDispatchToAddLogging(next) {
    return function dispatchAndLog(action) {
      console.log('dispatching', action)
      let result = next(action)
      console.log('next state', store.getState())
      return result
    }
  }
}

  es6写法

const logger = store => next => action => {
  console.log('dispatching', action)
  let result = next(action)
  console.log('next state', store.getState())
  return result
}

const crashReporter = store => next => action => {
  try {
    return next(action)
  } catch (err) {
    console.error('Caught an exception!', err)
    Raven.captureException(err, {
      extra: {
        action,
        state: store.getState()
      }
    })
    throw err
  }
}
function applyMiddleware(store, middlewares) {
  middlewares = middlewares.slice()
  middlewares.reverse()

  let dispatch = store.dispatch
  middlewares.forEach(middleware =>
    dispatch = middleware(store)(dispatch)
  )

  return Object.assign({}, store, { dispatch })
}
相关文章
相关标签/搜索