zoukankan      html  css  js  c++  java
  • 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!'
    
  • 相关阅读:
    对话框中设置静态文本框字体及颜色
    UVA 10250 The Other Two Trees(几何)
    UVA 113 Power of Cryptography(数学)
    VC++设置半透明界面
    UVA 10474 Where is the Marble?
    UVA 123 Searching Quickly(分离单词)
    为对话框在标题栏和任务栏关联图标
    UVA 152 Tree's a Crowd
    UVA 156 Ananagrams
    UVA 299 Train Swapping(冒泡排序)
  • 原文地址:https://www.cnblogs.com/lightsong/p/10440824.html
Copyright © 2011-2022 走看看