6、redux源码解析 - 中间件源码剖析

//源码使用方法
import {createStore, applyMiddleWare} from ‘redux‘;
//createStore.js的源码
export default function createStore(reducer, preloadState, enhancer) {
    //...
    if(typeof enhancer !== ‘undefined‘){
        if(typeof enhancer !== ‘function‘){
            throw new Error(‘...‘)
        }
    }  //enhancer是一个增加强器,是可选参数。是applyMiddelWare的返回值即一个函数
return enhancer(createStore)(reducer, preloadState); }
//顾名思义, applyMiddleWare就是对各个需要应用的中间件进行糅合,并作为createStore的
//第二个或者第三个参数传入,用于增强store。源码如下:
export default function applyMiddleWare(...middlewares){
    return (next) => (reducer, initialState) => {
        var store = next(reducer, initialState);
        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
        }
    }
}
//分析:
export default function applyMiddleware(...middlewares);
//这里使用了扩展运算符,使得applyMiddleware可以接收任意个数的中间件。接下来,
//applyMiddleware会返回一个函数,这个函数接收了一个next参数:
return (next) => (reducer, initialState) => {
    //...
}
//对应于createStore.js代码,applyMiddelware作为一个三级柯里化的函数,它的执行相当于:
applyMiddleware(...middlewares)(store)(reducer, initialState);
//这样做的目的是借用原始的createStore方法,创建一个增强版store,具体看其内容实现:
var store = createStore(reducer, initialState);
var dispatch = store.dispatch;
var chain = []
//这里记录了原始的store和store.dispatch方法,并准备了一个chain数组
var middlewareAPI = {
    getState: store.getState,
    dispatch: (action) => dispatch(action)
}
var chain = middlewares.map(middleware => middleware(middlewareAPI));
//middlewareAPI是第三方中间件需要使用的参数,即原始的store.getState 和dispatch方法,
//这些参数在中间件中是否会全部应用到,自然要看每个中间件的应用场景和需求。
//可以想象chain数组中每一项都是对原始dispatch的增强,并进行控制权转移。所以就有了 dispatch = compose(...chain, store.dispatch)
//这里的dispatch函数就是增强后的dispatch。因此,compose 方法接收了chain数组和原始的store.dispatch方法。
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)));
}
//实际上,compose方法就像是把多个中间件串联起来,就像
// middlewareA( middlewareB( middlewareC(store.dispatch) ) )
 

原文地址:https://www.cnblogs.com/hellolol/p/11416572.html

时间: 2024-10-11 13:16:05

6、redux源码解析 - 中间件源码剖析的相关文章

GlusterFS源码解析 —— GlusterFS 源码安装

安装环境: CentOS6.2 glusterfs-3.4.3 GlusterFS 挂载需要 fuse 支持,如果你的内核版本低于 2.6.16 则需要下载fuse的源码包自行编译安装,也可下载 fuse 的rpm包.安装fuse的方法我就不说了,不会源码安装的直接去rpmfind.net上下载rpm即可.高于此版本的内核中已经有了fuse.ko的模块,需要的时候可以执行以下命令进行加载: modprobe -b fuse 1.下载GlusterFS的源码包,目前已经有更新版本 : wget h

Java生成二维码解析二维码

package QrCode; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.imageio.ImageIO; import com.google.zxing.BarcodeFormat; imp

spring源码解析——spring源码导入eclipse

一.前言     众所周知,spring的强大之处.几乎所有的企业级开发中,都使用了spring了.在日常的开发中,我们是否只知道spring的配置,以及简单的使用场景.对其实现的代码没有进行深入的了解.开卷有益,在我们空闲的时间里面阅读一下spring的源码,对提升我们的自身能力还是还有很大的帮忙.下面总结一下spring源码导入eclipse的具体的操作. 二.spring的特点 spring的的核心就是IOC(控制反转)和AOP(基于切面的编程) 事务管理方面采用了:声明式事务 为各种主流

Curator源码解析(一)源码结构和测试程序

Curator是Netflix开源的一套ZooKeeper客户端框架. Netflix在使用ZooKeeper的过程中发现ZooKeeper自带的客户端太底层, 应用方在使用的时候需要自己处理很多事情, 于是在它的基础上包装了一下, 提供了一套更好用的客户端框架. Netflix在用ZooKeeper的过程中遇到的问题, 我们也遇到了, 所以开始研究一下, 首先从他在github上的源码, wiki文档以及Netflix的技术blog入手. 看完官方的文档之后, 发现Curator主要解决了三类

MIT 2012分布式课程基础源码解析一-源码概述

课程主页 课程介绍:本课程会在给出的源码的基础上要求完成8个lab lab overviewLab 1 - Lock ServerLab 2 - Basic File ServerLab 3 - MKDIR, UNLINK, and LockingLab 4 - Caching Lock ServerLab 5 - Caching Extent Server + ConsistencyLab 6 - PaxosLab 7 - Replicated lock serverLab 8 - Proje

Java源码解析|String源码与常用方法

String源码与常用方法 1.栗子 代码: public class JavaStringClass { public static void main(String[] args) { String s ="hello"; s = "world"; //内存地址已经修改 原来地址上的值还是不变的 String s2 = "hello"; //从常量值中找到并引用 String s4 = new String("hello"

Dialog与FragmentDialog源码解析

<代码里的世界> -UI篇 用文字札记描绘自己 android学习之路 转载请保留出处 by Qiao http://blog.csdn.net/qiaoidea/article/details/46402845 [导航] - 弹出式对话框各种方案 从仿QQ消息提示框来谈弹出式对话框的实现方式 (Dialog,PopupWind,自定义View,Activity,FragmentDialog) - Dialog源码解析 从源码上看Dialog与DialogFragment 1.概述 前一篇写了

Android 开源项目源码解析(第二期)

Android 开源项目源码解析(第二期) 阅读目录 android-Ultra-Pull-To-Refresh 源码解析 DynamicLoadApk 源码解析 NineOldAnimations 源码解析 SlidingMenu 源码解析 Cling 源码解析 BaseAdapterHelper 源码分析 Side Menu.Android 源码解析 DiscreteSeekBar 源码解析 CalendarListView 源码解析 PagerSlidingTabStrip 源码解析 公共

ThreadingTCPServer源码解析

实例 #!/usr/bin/env python #-*- coding:utf-8 -*- import SocketServer class Myserver(SocketServer.BaseRequestHandler): def handle(self): conn = self.request print self.client_address conn.sendall("我能同时处理多个请求!") flag = True while flag: data = conn.r