深入理解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 相关文章推荐
在修改准备发的批量美化select+可修改select时,在非IE下发现了几个问题
Jan 09 Javascript
通过Unicode转义序列来加密,按你说的可以算是混淆吧
May 06 Javascript
JavaScript实现复制功能各浏览器支持情况实测
Jul 18 Javascript
jQuery中ajax的post()方法用法实例
Dec 26 Javascript
JavaScript中计算网页中某个元素的位置
Jun 10 Javascript
JS获取数组最大值、最小值及长度的方法
Nov 24 Javascript
JavaScript保留关键字汇总
Dec 01 Javascript
详解本地Node.js服务器作为api服务器的解决办法
Feb 28 Javascript
Angularjs验证用户输入的字符串是否为日期时间
Jun 01 Javascript
基于angular2 的 http服务封装的实例代码
Jun 29 Javascript
vue改变循环遍历后的数据实例
Nov 07 Javascript
Vue+element-ui添加自定义右键菜单的方法示例
Dec 08 Vue.js
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
php 图片上添加透明度渐变的效果
2009/06/29 PHP
PHP 面向对象程序设计(oop)学习笔记(三) - 单例模式和工厂模式
2014/06/12 PHP
PHP中使用sleep函数实现定时任务实例分享
2014/08/21 PHP
php单例模式实现方法分析
2015/03/14 PHP
PHP入门教程之面向对象基本概念实例分析
2016/09/11 PHP
浅析PHP类的反射来实现依赖注入过程
2018/02/06 PHP
JavaScript 精粹读书笔记(1,2)
2010/02/07 Javascript
Js sort排序使用方法
2011/10/17 Javascript
关于textarea提交的内容无法换行的解决办法
2013/04/09 Javascript
JavaScript Sort 的一个错误用法示例
2015/03/20 Javascript
完美兼容多浏览器的js判断图片路径代码汇总
2015/04/17 Javascript
Bootstrap基本插件学习笔记之Popover提示框(19)
2016/12/08 Javascript
AngularJS实现网站换肤实例
2021/02/19 Javascript
jQuery实现下拉菜单的实例代码
2017/06/19 jQuery
微信小程序使用progress组件实现显示进度功能【附源码下载】
2017/12/12 Javascript
详解vue组件开发脚手架
2018/06/15 Javascript
js的新生代垃圾回收知识点总结
2019/08/22 Javascript
原理深度解析Vue的响应式更新比React快
2020/04/04 Javascript
简单文件操作python 修改文件指定行的方法
2013/05/15 Python
简单的python后台管理程序
2017/04/13 Python
python 对dataframe下面的值进行大规模赋值方法
2018/06/09 Python
python自动发送邮件脚本
2018/06/20 Python
对python3中的RE(正则表达式)-详细总结
2019/07/23 Python
简单的Python人脸识别系统
2020/07/14 Python
英国汽车和货车租赁网站:Hertz英国
2016/09/02 全球购物
意大利专业化妆品品牌:KIKO MILANO
2017/02/01 全球购物
实习销售业务员自我鉴定
2013/09/21 职场文书
银行营业厅大堂经理岗位职责
2014/01/06 职场文书
市场部规章制度
2014/01/24 职场文书
股东合作协议书
2014/04/14 职场文书
贯彻落实“八项规定”思想汇报
2014/09/13 职场文书
公司租房协议书范本
2014/10/08 职场文书
无子女夫妻离婚协议书(4篇)
2014/10/20 职场文书
2019职场单身人才调研报告:互联网行业单身比例最高
2019/08/07 职场文书
JavaScript继承的三种方法实例
2021/05/12 Javascript
Java9新特性对HTTP2协议支持与非阻塞HTTP API
2022/03/16 Java/Android