美文网首页
关于redux中的Middleware

关于redux中的Middleware

作者: 7天苹果 | 来源:发表于2017-05-20 16:36 被阅读127次

什么是Redux中间件 ?

redux 提供了类似后端 Express 的中间件概念,本质的目的是提供第三方插件的模式,自定义拦截 action -> reducer 的过程。变为 action -> middlewares -> reducer 。redux中的中间件可以使得在用户调用store.dispatch之后,先对参数state和actions进行预处理,再让真正的store.dispatch调用,以确保reducer的纯度(函数式编程的概念)不变。


applyMiddleware源码分析

下面是 applyMiddleware 完整的代码,参数为 middlewares 数组:



import compose from './compose'

export default function applyMiddleware(...middlewares) {
  return (createStore) => (reducer, preloadedState, enhancer) => {
    var store = createStore(reducer, preloadedState, enhancer)
    var dispatch = store.dispatch
    var chain = []

    var middlewareAPI = {
      getState: store.getState,
      dispatch: (action) => dispatch(action)
    }
    chain = middlewares.map(middleware => middleware(middlewareAPI))
    dispatch = compose(...chain)(store.dispatch)

    return {
      ...store,
      dispatch
    }
  }
}

1.applyMiddleware 执行过后返回一个闭包函数,目的是将创建 store的步骤放在这个闭包内执行,这样 middleware 就可以共享 store 对象。

2.middlewares 数组 map 为新的 middlewares 数组,包含了 middlewareAPI

3.compose 方法将新的 middlewares 和 store.dispatch 结合起来,生成一个新的 dispatch 方法

4.返回的 store 新增了一个 dispatch 方法, 这个新的 dispatch 方法是改装过的 dispatch,也就是封装了中间件的执行。

所以关键点来到了 compose 方法了,下面来看一下 compose 的设计:

export default function compose(...funcs) {
  if (funcs.length === 0) {
    return arg => arg
  }

  if (funcs.length === 1) {
    return funcs[0]
  }

  const last = funcs[funcs.length - 1]
  const rest = funcs.slice(0, -1)
  return (...args) => rest.reduceRight((composed, f) => f(composed), last(...args))

可以看到 compose 方法实际上就是利用了 Array.prototype.reduceRight 。如果对 reduceRight 不是很熟悉,来看看下面的一个例子就清晰了:

[0, 1, 2, 3, 4].reduceRight(function(previousValue, currentValue, index, array) {
  return previousValue + currentValue;
}, 10);

执行结果:

执行结果

理解中间件的执行过程

通过上面的 applyMiddleware 和 中间件的结构,假设应用了如下的中间件: [A, B, C],一个 action 的完整执行流程:

初始化阶段:

一个中间件的结构:

function ({getState}) {
    return function (next) {
        return function (action) {...}
    }
}

初始化阶段一:middlewares map 为新的 middlewares

chain = middlewares.map(middleware => middleware(middlewareAPI))

执行过后,middleware 变为了

function (next) {
    return function (action) {...}
}

初始化阶段二:compose 新的 dispatch

const newDispatch = compose(newMiddlewares)(store.dispatch)

dispatch 的实现为 reduceRight, 当一个新的 action 来了过后

/**
 * 1. 初始值为: lastMiddleware(store.dispatch)
 * 2. previousValue: composed
 * 3. currentValue: currentMiddleware
 * 4. return value: currentMiddleware(composed) => newComposed
 */
rest.reduceRight((composed, f) => f(composed), last(...args))

composed 流程

初始时候

initialValue: composedC = C(store.dispatch) = function C(action) {}

next 闭包: store.dispatch

第一次执行:

previousValue(composed): composedC

currentValue(f): B

return value: composedBC = B(composedC) = function B(action){}

next 闭包 composedC

第二次执行:

previousValue(composed): composedBC

currentValue(f): A

return value: composedABC = A(composedBC) = function A(action){}

next 闭包 composedBC

最后的返回结果为 composedABC

执行阶段

dispatch(action) 等于 composedABC(action) 等于执行 function A(action) {...}

在函数 A 中执行 next(action), 此时 A 中 next 为 composedBC,那么等于执行 composedBC(action) 等于执行function B(action){...}

在函数 B 中执行 next(action), 此时 B 中 next 为 composedC,那么等于执行 composedC(action) 等于执行function C(action){...}

在函数 C 中执行 next(action), 此时 C 中 next 为 store.dispatch 即 store 原生的 dispatch, 等于执行store.dispatch(action)

store.dispatch 会执行 reducer 生成最新的 store 数据

所有的 next 执行完过后开始回溯

执行函数 C 中 next 后的代码

执行函数 B 中 next 后的代码

执行函数 A 中 next 后的代码

整个执行 action 的过程为 A -> B -> C -> dispatch -> C -> B -> A

相关文章

  • 关于redux中的Middleware

    什么是Redux中间件 ? redux 提供了类似后端 Express 的中间件概念,本质的目的是提供第三方插件的...

  • 浅析Redux 的 store enhancer

    相信大家都知道Redux的middleware(中间件)的概念,Redux通过middleware可以完成发送异步...

  • redux中的Middleware

    1. 什么是middlewware 是dispatch分发action和action到达reducer的中间件 2...

  • redux-applyMiddleware

    redux 中的middleware思想还是很巧妙地,先来看下怎么使用 就是将middleware 使用apply...

  • redux middleware

    middleware redux middlewarwe middleware 提供了一个分类处理 action ...

  • redux middleware 理解中

    redux@4.0.0 logger()(dispatch) 返回的是最里层的函数,该函数作为参数传递给了thun...

  • Redux中middleware小结

    为什么出现middleware? 为了解决异步操作。 middleware如何处理异步的? Action 发出以后...

  • redux中的middleware解析

    为什么需要middleware 在没有middleware之前,Redux的工作流程是这样的 理解middlewa...

  • Redux Middleware

    以记录日志为示例来说明 尝试#1:手动记录 尝试#2:隐藏Monkeypatching 尝试 #3: 移除 Mon...

  • react 面试

    react redux (所有数据都放入redux管理) 1、redux中间件原理(middleware) 中间件...

网友评论

      本文标题:关于redux中的Middleware

      本文链接:https://www.haomeiwen.com/subject/mgfpxxtx.html