Stay Hungry,Stay Foolish!

Redux中间件组合方法

中间件

https://redux.js.org/glossary#middleware

中间件在发送端 action端点 和 处理方reducer的端点之间。

主要负责将async action转换为action, 或者记录action日志。

A middleware is a higher-order function that composes a dispatch function to return a new dispatch function. It often turns async actions into actions.

Middleware is composable using function composition. It is useful for logging actions, performing side effects like routing, or turning an asynchronous API call into a series of synchronous actions.

 

import { createStore, applyMiddleware } from 'redux'
import todos from './reducers'

function logger({ getState }) {
  return next => action => {
    console.log('will dispatch', action)

    // Call the next dispatch method in the middleware chain.
    const returnValue = next(action)

    console.log('state after dispatch', getState())

    // This will likely be the action itself, unless
    // a middleware further in chain changed it.
    return returnValue
  }
}

const store = createStore(todos, ['Use Redux'], applyMiddleware(logger))

store.dispatch({
  type: 'ADD_TODO',
  text: 'Understand the middleware'
})
// (These lines will be logged by the middleware:)
// will dispatch: { type: 'ADD_TODO', text: 'Understand the middleware' }
// state after dispatch: [ 'Use Redux', 'Understand the middleware' ]

 

 

http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_two_async_operations.html


let next = store.dispatch;
store.dispatch = function dispatchAndLog(action) {
  console.log('dispatching', action);
  next(action);
  console.log('next state', store.getState());
}

上面代码中,对store.dispatch进行了重定义,在发送 Action 前后添加了打印功能。这就是中间件的雏形。

中间件就是一个函数,对store.dispatch方法进行了改造,在发出 Action 和执行 Reducer 这两步之间,添加了其他功能。

 

应用多个中间件

https://redux.js.org/api/applymiddleware

applyMiddleware(...middleware)

Middleware is the suggested way to extend Redux with custom functionality. Middleware lets you wrap the store's dispatch method for fun and profit. The key feature of middleware is that it is composable. Multiple middleware can be combined together, where each middleware requires no knowledge of what comes before or after it in the chain.

 

Arguments

  • ...middleware (arguments): Functions that conform to the Redux middleware API. Each middleware receives Store's dispatch and getState functions as named arguments, and returns a function. That function will be given the next middleware's dispatch method, and is expected to return a function of action calling next(action) with a potentially different argument, or at a different time, or maybe not calling it at all. The last middleware in the chain will receive the real store's dispatch method as the next parameter, thus ending the chain. So, the middleware signature is ({ getState, dispatch }) => next => action.

 

Returns

(Function) A store enhancer that applies the given middleware. The store enhancer signature is createStore => createStore but the easiest way to apply it is to pass it to createStore() as the last enhancer argument.

 

应用中间件函数实现, 注意其中 对于middlewares数组, 使用compose函数进行组合, 其串联方式是从 右 到 左, 即最右边的被包裹为最里层,最先执行, 最左边的被包裹到最外面, 最后执行。

https://www.cnblogs.com/liaozhenting/p/10166671.html

export default function applyMiddleware(...middlewares) {
  return createStore => (...args) => {
    const store = createStore(...args)
    let dispatch = () => {
      throw new Error(
        `Dispatching while constructing your middleware is not allowed. ` +
          `Other middleware would not be applied to this dispatch.`
      )
    }

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

    return {
      ...store,
      dispatch
    }
  }
}

 

如下图很形象:

https://zhuanlan.zhihu.com/p/20597452

 

 

 

 compose

https://www.cnblogs.com/liaozhenting/p/10166671.html

/**
 * Composes single-argument functions from right to left. The rightmost
 * function can take multiple arguments as it provides the signature for
 * the resulting composite function.
 *
 * @param {...Function} funcs The functions to compose.
 * @returns {Function} A function obtained by composing the argument functions
 * from right to left. For example, compose(f, g, h) is identical to doing
 * (...args) => f(g(h(...args))).
 */

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

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

  return funcs.reduce((a, b) => (...args) => a(b(...args)))
}

 

与pipe正好相反:

const pipe = (...fns) => {
  return (args) => {
    return fns.reduce((args, fn) => {
      return fn(args)
    }, args)
  }
}

const toUpper = (value) => {
  return value.toUpperCase();
}

const addFont = (value) => {
  return 'hello plus!' + value;
}

console.log(pipe(addFont,toUpper)('test'));
// HELLO PLUS!TEST

 

跟pip函数对比

console.log(pipe(addFont,toUpper)('test'));
// HELLO PLUS!TEST

console.log(compose(addFont,toUpper)('test'));
// hello plus!TEST

 

underscore compose

http://www.bootcss.com/p/underscore/#compose

compose_.compose(*functions)
返回函数集 functions 组合后的复合函数, 也就是一个函数执行完之后把返回的结果再作为参数赋给下一个函数来执行. 以此类推. 在数学里, 把函数 f(), g(), 和 h() 组合起来可以得到复合函数 f(g(h()))

var greet    = function(name){ return "hi: " + name; };
var exclaim  = function(statement){ return statement.toUpperCase() + "!"; };
var welcome = _.compose(greet, exclaim);
welcome('moe');
=> 'hi: MOE!'

 

posted @ 2019-02-26 22:58  lightsong  阅读(372)  评论(0编辑  收藏  举报
Life Is Short, We Need Ship To Travel