深入理解redux之compose的具体应用


Posted in Javascript onJanuary 12, 2020

应用

最近给自己的react项目添加redux的时候,用到了redux中的compose函数,使用compose来增强store,下面是我在项目中的一个应用:

import {createStore,applyMiddleware,compose} from 'redux';
import createSagaMiddleware from 'redux-saga';
const sagaMiddleware = createSagaMiddleware();
const middlewares = [];

let storeEnhancers = compose(
  applyMiddleware(...middlewares,sagaMiddleware),
  (window && window .devToolsExtension) ? window .devToolsExtension() : (f) => f,
);

const store = createStore(rootReducer, initialState={} ,storeEnhancers);

上面这段代码可以让store与 applyMiddleware 和 devToolsExtension 一起使用。

reduce方法

在理解compose函数之前先来认识下什么是reduce方法?
官方文档上是这么定义reduce方法的:

reduce() 方法对累加器和数组中的每个元素(从左到右)应用一个函数,将其简化为单个值。

看下函数签名:

arr.reduce(callback[, initialValue])

callback

执行数组中每个值的函数,包含四个参数:

accumulator(累加器)
累加器累加回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue。

currentValue(当前值)
数组中正在处理的元素。

currentIndex可选(当前索引)
数组中正在处理的当前元素的索引。 如果提供了initialValue,则索引号为0,否则为索引为1。

array可选(数组)
调用reduce()的数组

initialValue可选(初始值)
用作第一个调用 callback的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初 始值的空数组上调用 reduce 将报错。

下面看一个简单的例子:

数组求和

var sum = [0, 1, 2, 3].reduce(function (a, b) {
 return a + b;
}, 0);
// sum 值为 6

这个例子比较简单,下面再看个稍微复杂点的例子,计算数组中每个元素出现的次数:

var series = ['a1', 'a3', 'a1', 'a5', 'a7', 'a1', 'a3', 'a4', 'a2', 'a1'];

var result= series.reduce(function (accumulator, current) {
  if (current in accumulator) {
    accumulator[current]++;
  }
  else {
    accumulator[current] = 1;
  }
  return accumulator;
}, {});

console.log(JSON.stringify(result));
// {"a1":4,"a3":2,"a5":1,"a7":1,"a4":1,"a2":1}

这个例子很巧妙的利用了数组的reduce方法,在很多算法面试题中也经常用到。这里需要注意的是需要指定initialValue参数。

通过reduce函数还可以实现数组去重:

var a = [1, 1, 2, 3, 4, 4, 5, 6, 6, 6, 7];
Array.prototype.duplicate = function() {
  return this.reduce(function(cal, cur) {
    if(cal.indexOf(cur) === -1) {
      cal.push(cur);
    }
    return cal;
  }, [])
}

var newArr = a.duplicate();

compose函数

理解完了数组的reduce方法之后,就很容易理解compose函数了,因为实际上compose就是借助于reduce来实现的。看下官方源码:

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的返回值还是一个函数,调用这个函数所传递的参数将会作为compose最后一个参数的参数,从而像'洋葱圈'似的,由内向外,逐步调用。

看下面的例子:

import { compose } 'redux';

// function f
const f = (arg) => `函数f(${arg})` 

// function g
const g = (arg) => `函数g(${arg})`

// function h 最后一个函数可以接受多个参数
const h = (...arg) => `函数h(${arg.join('_')})`

console.log(compose(f,g,h)('a', 'b', 'c')) //函数f(函数g(函数h(a_b_c)))

所以最后返回的就是这样的一个函数 compose(fn1, fn2, fn3) (...args) = > fn1(fn2(fn3(...args))) 。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
模仿jQuery each函数的链式调用
Jul 22 Javascript
解决JS浮点数运算出现Bug的方法
Mar 12 Javascript
清除div下面的所有标签的方法
Feb 17 Javascript
使用jQuery实现验证上传图片的格式与大小
Dec 03 Javascript
JS实现下拉菜单赋值到文本框的方法
Aug 18 Javascript
JS学习之表格的排序简单实例
May 16 Javascript
Bootstrap基本样式学习笔记之表格(2)
Dec 07 Javascript
javascript实现一个网页加载进度loading
Jan 04 Javascript
JS获得多个同name 的input输入框的值的实现方法
Jan 09 Javascript
Angularjs实现上传图片预览功能
Sep 01 Javascript
vue实现绑定事件的方法实例代码详解
Jun 20 Javascript
基于layui的下拉列表的数据回显方法
Sep 24 Javascript
2019年度web前端面试题总结(主要为Vue面试题)
Jan 12 #Javascript
html2canvas属性和使用方法以及如何使用html2canvas将HTML内容写入Canvas生成图片
Jan 12 #Javascript
ES2020 新特性(种草)
Jan 12 #Javascript
在微信小程序中渲染HTML内容3种解决方案及分析与问题解决
Jan 12 #Javascript
es6 for循环中let和var区别详解
Jan 12 #Javascript
js 计数排序的实现示例(升级版)
Jan 12 #Javascript
JS实现动态无缝轮播
Jan 11 #Javascript
You might like
当海贼王变成JOJO风
2020/03/02 日漫
鸡肋的PHP单例模式应用详解
2013/06/03 PHP
php中文验证码实现示例分享
2014/01/12 PHP
php获取文件夹路径内的图片以及分页显示示例
2014/03/11 PHP
php实现的click captcha点击验证码类实例
2014/09/23 PHP
第一次动手实现bootstrap table分页效果
2016/09/22 Javascript
详解AngularJs路由之Ui-router-resolve(预加载)
2017/06/13 Javascript
js实现移动端轮播图效果
2020/12/09 Javascript
JavaScript动态创建二维数组的方法示例
2019/02/01 Javascript
vue-cli3 项目优化之通过 node 自动生成组件模板 generate View、Component
2019/04/30 Javascript
用python实现面向对像的ASP程序实例
2014/11/10 Python
Python实现两个list对应元素相减操作示例
2017/06/09 Python
python初学之用户登录的实现过程(实例讲解)
2017/12/23 Python
Python实现的寻找前5个默尼森数算法示例
2018/03/25 Python
Python设计模式之状态模式原理与用法详解
2019/01/15 Python
解决Python 命令行执行脚本时,提示导入的包找不到的问题
2019/01/19 Python
python代理工具mitmproxy使用指南
2019/07/04 Python
python实现复制大量文件功能
2019/08/31 Python
关于Numpy数据类型对象(dtype)使用详解
2019/11/27 Python
关于ResNeXt网络的pytorch实现
2020/01/14 Python
解决pytorch-yolov3 train 报错的问题
2020/02/18 Python
Python Opencv 通过轨迹(跟踪)栏实现更改整张图像的背景颜色
2020/03/09 Python
PyTorch 导数应用的使用教程
2020/08/31 Python
Python利用matplotlib绘制散点图的新手教程
2020/11/05 Python
Python 爬取淘宝商品信息栏目的实现
2021/02/06 Python
html5表单及新增的改良元素详解
2016/06/07 HTML / CSS
丝芙兰墨西哥官网:Sephora墨西哥
2020/05/30 全球购物
介绍一下Linux内核的排队自旋锁
2014/01/04 面试题
外贸主管求职简历的自我评价
2013/10/23 职场文书
哈理工毕业生的求职信
2013/12/22 职场文书
项目建议书模板
2014/05/12 职场文书
建筑工地宣传标语
2014/06/18 职场文书
小学数学教研活动总结
2014/07/01 职场文书
一篇文章弄懂MySQL查询语句的执行过程
2021/05/07 MySQL
Win11开始菜单添加休眠选项
2022/04/19 数码科技
MySQL事务的ACID特性以及并发问题方案
2022/07/15 MySQL