深入理解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 相关文章推荐
Flash+XML滚动新闻代码 无图片 附源码下载
Nov 22 Javascript
jQuery控制图片的hover效果(smartRollover.js)
Mar 18 Javascript
javascript数字时钟示例分享
Apr 23 Javascript
js获取鼠标点击的位置实现思路及代码
May 09 Javascript
js中document.write的那点事
Dec 12 Javascript
jQuery显示和隐藏 常用的状态判断方法
Jan 29 Javascript
js阻止默认浏览器行为与冒泡行为的实现代码
May 15 Javascript
浅谈Angular路由守卫
Aug 26 Javascript
详解Node.js amqplib 连接 Rabbit MQ最佳实践
Jan 24 Javascript
详解使用webpack+electron+reactJs开发windows桌面应用
Feb 01 Javascript
通过实例解析JavaScript常用排序算法
Sep 02 Javascript
JS使用setInterval计时器实现挑战10秒
Nov 08 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
PHP+MYSQL的文章管理系统(二)
2006/10/09 PHP
浅谈php正则表达式中的非贪婪模式匹配的使用
2014/11/25 PHP
PHP类型约束用法示例
2016/09/28 PHP
把textarea中字符串里含有的回车换行替换成<br>的javascript代码
2007/04/20 Javascript
基于Asp.net与Javascript控制的日期控件
2010/05/22 Javascript
jQuery Ajax 仿AjaxPro.Utility.RegisterTypeForAjax辅助方法
2011/09/27 Javascript
JavaScript 用Node.js写Shell脚本[译]
2012/09/20 Javascript
jquery事件preventDefault()方法用法实例
2015/01/16 Javascript
Javascript基础教程之比较操作符
2015/01/18 Javascript
jquery.form.js实现将form提交转为ajax方式提交的方法
2015/04/07 Javascript
jquery表单插件Autotab使用方法详解
2016/06/24 Javascript
bootstrap快速制作后台界面
2016/12/05 Javascript
AngularJS 异步解决实现方法
2017/06/12 Javascript
收集前端面试题之url、href、src
2018/03/22 Javascript
浅谈vue-cli 3.0.x 初体验
2018/04/11 Javascript
AngularJS与BootStrap模仿百度分页的示例代码
2018/05/23 Javascript
angularJs中跳转到指定的锚点实例($anchorScroll)
2018/08/31 Javascript
vue实现的树形结构加多选框示例
2019/02/02 Javascript
深入了解Hybrid App技术的相关知识
2019/07/17 Javascript
layui 实现table翻页滚动条位置保持不变的例子
2019/09/05 Javascript
JavaScript组合设计模式--改进引入案例分析
2020/05/23 Javascript
[03:11]DOTA2上海特锦赛小组赛第一日recap精彩回顾
2016/02/28 DOTA
[01:33]真香警告!DOTA2勇士令状不朽珍藏Ⅱ饰品欣赏
2018/06/26 DOTA
[02:19]2018年度DOTA2最佳核心位选手-完美盛典
2018/12/17 DOTA
使用python 获取进程pid号的方法
2014/03/10 Python
在Python程序和Flask框架中使用SQLAlchemy的教程
2016/06/06 Python
详解python函数传参是传值还是传引用
2018/01/16 Python
python实现RabbitMQ的消息队列的示例代码
2018/11/08 Python
python中partial()基础用法说明
2018/12/30 Python
Python简单实现区域生长方式
2020/01/16 Python
PyTorch中Tensor的数据统计示例
2020/02/17 Python
经理秘书找工作求职信
2013/12/19 职场文书
班主任工作经验交流材料
2014/05/13 职场文书
夏季药店促销方案
2014/08/22 职场文书
古诗之爱国古诗5首
2019/09/20 职场文书
uniapp 微信小程序 自定义tabBar 导航
2022/04/22 Javascript