深入理解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 拼图游戏 面向对象,注释完整。
Jun 18 Javascript
Document 对象的常用方法
Jul 31 Javascript
基于jquery实现的服务器验证控件的启用和禁用代码
Apr 27 Javascript
当json键为数字时的取值方法解析
Nov 15 Javascript
jquery实现兼容IE8的异步上传文件
Jun 15 Javascript
jQuery带时间的日期控件代码分享
Aug 26 Javascript
JavaScript实现倒计时代码段Item1(非常实用)
Nov 03 Javascript
jquery实现数字输入框
Feb 22 Javascript
React组件中的this的具体使用
Feb 28 Javascript
Vue+Express实现登录状态权限验证的示例代码
May 05 Javascript
vue中的计算属性和侦听属性
Nov 06 Javascript
H5 js点击按钮复制文本到粘贴板
Nov 19 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
ThinkPHP路由机制简介
2016/03/23 PHP
php微信开发之关注事件
2018/06/14 PHP
Laravel框架模型的创建及模型对数据操作示例
2019/05/07 PHP
用js计算页面执行时间的函数
2006/12/07 Javascript
javascript 验证日期的函数
2010/03/18 Javascript
jquery异步调用页面后台方法‏(asp.net)
2011/03/01 Javascript
IE6、IE7中setAttribute不支持class/for/rowspan/colspan等属性
2011/08/28 Javascript
js树插件zTree获取所有选中节点数据的方法
2015/01/28 Javascript
js随机生成网页背景颜色的方法
2015/02/26 Javascript
javascript中clipboardData对象用法详解
2015/05/13 Javascript
jquery 中ajax执行的优先级
2015/06/22 Javascript
基于jQuery实现弹出可关闭遮罩提示框实例代码
2016/07/18 Javascript
AngularJS ng-bind-template 指令详解
2016/07/30 Javascript
AngularJS基础 ng-csp 指令详解
2016/08/01 Javascript
根据Bootstrap Paginator改写的js分页插件
2016/12/25 Javascript
不得不知的ES6小技巧
2018/07/28 Javascript
vue2.x 通过后端接口代理,获取qq音乐api的数据示例
2019/10/30 Javascript
Python Web框架Pylons中使用MongoDB的例子
2013/12/03 Python
python开发之list操作实例分析
2016/02/22 Python
python批量图片处理简单示例
2019/08/06 Python
python实现串口通信的示例代码
2020/02/10 Python
Python读取JSON数据操作实例解析
2020/05/18 Python
CSS3动画:5种预载动画效果实例
2017/04/05 HTML / CSS
CSS3 按钮边框动画的实现
2020/11/12 HTML / CSS
Room Mate Hotels美国:西班牙酒店品牌
2018/04/10 全球购物
奥斯汀独木舟和皮划艇:Austin Canoe & Kayak
2018/05/22 全球购物
亚洲领先的设计购物网站:Pinkoi
2020/11/26 全球购物
企业安全生产标语
2014/06/06 职场文书
学雷锋的心得体会
2014/09/04 职场文书
2014年学习厉行节约反对浪费思想汇报
2014/09/10 职场文书
营销计划书
2015/01/17 职场文书
教师求职自荐信范文
2015/03/04 职场文书
2016年大学自主招生自荐信范文
2015/03/24 职场文书
redis内存空间效率问题的深入探究
2021/05/17 Redis
python实现学员管理系统(面向对象版)
2022/06/05 Python
CSS中calc(100%-100px)不加空格不生效
2023/05/07 HTML / CSS