深入理解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 AJAX回调函数this指向问题
Feb 08 Javascript
将查询条件的input、select清空
Jan 14 Javascript
js 判断控件获得焦点的示例代码
Mar 04 Javascript
JavaScript中遍历对象的property的3种方法介绍
Dec 30 Javascript
基于JavaScript如何实现私有成员的语法特征及私有成员的实现方式
Oct 28 Javascript
jQuery获得字体颜色16位码的方法
Feb 20 Javascript
jQuery文字轮播特效
Feb 12 Javascript
Vue组件开发初探
Feb 14 Javascript
Node.js常用工具之util模块
Mar 09 Javascript
vue中子组件的methods中获取到props中的值方法
Aug 27 Javascript
vue安装和使用scss及sass与scss的区别详解
Oct 15 Javascript
Vue实现搜索结果高亮显示关键字
May 28 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
分页显示Oracle数据库记录的类之二
2006/10/09 PHP
php实现无限级分类实现代码(递归方法)
2011/01/01 PHP
php方法调用模式与函数调用模式简例
2011/09/20 PHP
php 无法加载mysql的module的时候的配置的解决方案引发的思考
2012/01/27 PHP
PHP 伪静态技术原理以及突破原理实现介绍
2013/07/12 PHP
PHP中filter函数校验数据的方法详解
2015/07/31 PHP
PHP5.3连接Oracle客户端及PDO_OCI模块的安装方法
2016/05/13 PHP
js 操作select和option常用代码整理
2012/12/13 Javascript
jsp js鼠标移动到指定区域显示选项卡离开时隐藏示例
2013/06/14 Javascript
jQuery中prevUntil()方法用法实例
2015/01/08 Javascript
jQuery获取页面及个元素高度、宽度的总结——超实用
2015/07/28 Javascript
js游戏人物上下左右跑步效果代码分享
2015/08/28 Javascript
今天抽时间给大家整理jquery和ajax的相关知识
2015/11/17 Javascript
详解Bootstrap四种图片样式
2016/01/04 Javascript
ES6生成器用法实例分析
2017/04/10 Javascript
JS实现移动端整屏滑动的实例代码
2017/11/10 Javascript
vue双向数据绑定知识点总结
2018/04/18 Javascript
使用vuex较为优雅的实现一个购物车功能的示例代码
2019/12/09 Javascript
javascript设计模式 ? 策略模式原理与用法实例分析
2020/04/21 Javascript
vue点击标签切换选中及互相排斥操作
2020/07/17 Javascript
Vue解决echart在element的tab切换时显示不正确问题
2020/08/03 Javascript
vue 中this.$set 动态绑定数据的案例讲解
2021/01/29 Vue.js
python去掉字符串中重复字符的方法
2014/02/27 Python
Python 数据结构之堆栈实例代码
2017/01/22 Python
python 获取键盘输入,同时有超时的功能示例
2018/11/13 Python
python实现两个一维列表合并成一个二维列表
2019/12/02 Python
Jupyter打开图形界面并画出正弦函数图像实例
2020/04/24 Python
Python如何将装饰器定义为类
2020/07/30 Python
利用Pycharm + Django搭建一个简单Python Web项目的步骤
2020/10/22 Python
Ajax请求总共有多少种Callback
2016/07/17 面试题
小区门卫管理制度
2014/01/29 职场文书
汽车装潢店创业计划书范文
2014/02/05 职场文书
教师节随笔
2015/08/15 职场文书
外出听课学习心得体会
2016/01/15 职场文书
Python中生成随机数据安全性、多功能性、用途和速度方面进行比较
2022/04/14 Python
Go中使用gjson来操作JSON数据的实现
2022/08/14 Golang