深入理解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 相关文章推荐
JS操作数据库的实例代码
Oct 17 Javascript
jQuery实现锚点scoll效果实例分析
Mar 10 Javascript
js获取图片宽高的方法
Nov 25 Javascript
javascript实现任务栏消息提示的简单实例
May 31 Javascript
JavaScript制作弹出层效果
Dec 02 Javascript
angular+bootstrap的双向数据绑定实例
Mar 03 Javascript
详解vue项目的构建,打包,发布全过程
Nov 23 Javascript
js使用Promise实现简单的Ajax缓存
Nov 14 Javascript
JS数组方法reverse()用法实例分析
Jan 18 Javascript
javascript实现扫雷简易版
Aug 18 Javascript
Vue中使用Echarts仪表盘展示实时数据的实现
Nov 01 Javascript
three.js显示中文字体与tween应用详析
Jan 04 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
smarty section简介与用法分析
2008/10/03 PHP
php tp验证表单与自动填充函数代码
2012/02/22 PHP
浅析PHP的静态成员函数效率更高的原因
2014/06/13 PHP
利用PHP函数计算中英文字符串长度的方法
2014/11/11 PHP
php通过array_merge()函数合并两个数组的方法
2015/03/18 PHP
PHP实现的DES加密解密实例代码
2016/04/06 PHP
PHP正则匹配操作简单示例【preg_match_all应用】
2017/07/10 PHP
在laravel中实现将查询的对象转换为多维数组的函数
2019/10/21 PHP
js实现局部页面打印预览原理及示例代码
2014/07/03 Javascript
jquery获取radio值(单选组radio)
2014/10/16 Javascript
javascript中parseInt()函数的定义和用法分析
2014/12/20 Javascript
JS实现的自定义显示加载等待图片插件(loading.gif)
2016/06/17 Javascript
jQuery获取attr()与prop()属性值的方法及区别介绍
2016/07/06 Javascript
详解用node-images 打造简易图片服务器
2017/05/08 Javascript
vue.js 使用v-if v-else发现没有执行解决办法
2017/05/15 Javascript
Vue中添加手机验证码组件功能操作方法
2017/12/07 Javascript
select获取下拉框的值 下拉框默认选中方法
2018/02/28 Javascript
vue使用Font Awesome的方法步骤
2019/02/26 Javascript
javascript实现倒计时效果
2020/02/17 Javascript
python服务器与android客户端socket通信实例
2014/11/12 Python
利用Python的装饰器解决Bottle框架中用户验证问题
2015/04/24 Python
python获取外网IP并发邮件的实现方法
2017/10/01 Python
Python随机生成均匀分布在单位圆内的点代码示例
2017/11/13 Python
500行Python代码打造刷脸考勤系统
2019/06/03 Python
Python根据字典的值查询出对应的键的方法
2020/09/30 Python
CSS3实现缺角矩形,折角矩形以及缺角边框
2019/12/20 HTML / CSS
StubHub巴西:购买和出售您的门票
2016/07/22 全球购物
外语学院毕业生的自我鉴定
2013/11/28 职场文书
工程招投标邀请书
2014/01/30 职场文书
优秀体育委员自荐书
2014/01/31 职场文书
开学典礼策划方案
2014/05/28 职场文书
2015年信贷员工作总结
2015/04/28 职场文书
师德师风主题教育活动总结
2015/05/07 职场文书
劳保用品管理制度范本
2015/08/06 职场文书
2016年乡镇七一建党节活动总结
2016/04/05 职场文书
浅谈Redis主从复制以及主从复制原理
2021/05/29 Redis