解读只有99行的Redux(二)—— 中间件相关

解读只有99行的Redux(二)—— 中间件相关_第1张图片

原文发布在我的个人博客 解读只有99行的Redux(二) | 以太空间

一、概述

  在使用Redux的时候我们可能会遇到异步操作的问题,希望让 Reducer 在异步操作结束后自动执行,所以我们就用了中间件(middleware)。
  先看一下中间件的一般形式:

const middleware = store => reducer => next => {
    ...//这一行可能会获取store的state并使用
    let result = next(action);
    ...//这一行可能会获取store的state并使用
    return result
}

  在真正的Redux环境中,我们一般是这样使用中间件的:

const { createStore, applyMiddleware} = Redux

const store = createStore(reducer,
    applyMiddleware(loggerMiddleware, confirmationMiddleware)
);

  不过,因为我们现在解读的是slim-redux,所以我们这样使用

const { createStore, applyMiddleware} = Redux

const store = applyMiddleware(
    loggerMiddleware,
    confirmationMiddleware)(createStore)(reducer);

二、compose解读

export function compose(...funcs) {
  return arg => funcs.reduceRight((composed, f) => f(composed), arg);
}

  要想理解下面的applyMiddleware,就得先搞懂这个compose
  它的作用就是从右到左来组合多个函数,这是函数式编程中的方法,为了方便,被放到了 Redux 里。
  它需要合成的多个函数。预计每个函数都接收一个参数。它的返回值将作为一个参数提供给它左边的函数,以此类推。例外是最右边的参数可以接受多个参数,因为它将为由此产生的函数提供签名。
  compose(funcA, funcB, funcC) 形象为 compose(funcA(funcB(funcC())))

三、applyMiddleware解读

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

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

    return { ...store, dispatch };
  };
}

  applyMiddleware是一个高阶函数,我们从最内层的函数开始:
  首先调用createStore得到了一个store,然后保存这个storedispatchdispatch,再声明一个chain数组。
  对最外层函数applyMiddleware的剩余参数middlewares进行遍历,对每一个middleware,传入一个临时store{getState: store.getState, dispatch: (action) => dispatch(action)}作为参数调用它。根据上面middleware的形式,其结果是以下的形式的函数

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

  遍历结束后,chain数组里面每个元素都是类似上面这样的函数。

  最后使用compose函数将chain数组里面的每个函数元素组合起来最后传入store.dispatch
  整个调用过程类似下面的结构:

function (next1) {
  return function (next2) {
      return function (next3) {
          return next4(store.dispatch);
      }
  }
}

  经过层层封装,dispatch已经不是原来的dispatch。调用这个dispatch的时候,我们想要的功能都会在中间完成,整个调用过程如下图所示:
解读只有99行的Redux(二)—— 中间件相关_第2张图片

  最后解构store并返回,新的dispatch覆盖原来的dispatch

  以下是解读只有99行的Redux系列的其他两篇文章

  解读只有99行的Redux(一) 从创建一个store开始
  解读只有99行的Redux(三) 辅助函数和组合Reducer

你可能感兴趣的:(解读只有99行的Redux(二)—— 中间件相关)