前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >函数式编程之compose

函数式编程之compose

作者头像
前端知知
发布2022-09-29 19:14:56
4220
发布2022-09-29 19:14:56
举报
文章被收录于专栏:前端知知前端知知

前言

在日常工作中,经常会出现这样的情况:一个数据处理会经常某些步骤,比如字符串转大写处理、增加后缀处理等步骤;我们很容易的能写出这样的处理函数:

代码语言:javascript
复制
function handleString(str) {
 //step 1: 
 let upperString = str.toUpperCase();
 //step 2:
 let result = upperString + '!';
 return result;
}

每个处理步骤都可能需要在某种情况下使用,那么这种代码写法难以达到复用;将每个步骤单独作为一个函数,也需要不同的流程处理函数,如下:

代码语言:javascript
复制
//step 1: 
function toUpperCase(str) {
  return str.toUpperCase();
}
// step2: 
function addExteranl(str) {
 return str + '!';
}
function handleString(str) {
 let upperString = toUpperCase(str);
 let result = addExteranl(upperString);
 return result;
}

那么是否有更优雅的处理方式呢,那就是下文要介绍的compose

compose 初探

compose 在 redux 插件实现中有广泛的运用,我们首先来看一下 compose 的实现:

代码语言:javascript
复制
// refs: https://github.com/reduxjs/redux/blob/master/src/compose.ts
function compose(...funcs: Function[]) {
  if (funcs.length === 0) {
    // infer the argument type so it is usable in inference down the line
    return <T>(arg: T) => arg
  }

  if (funcs.length === 1) {
    return funcs[0]
  }

  return funcs.reduce((a, b) => (...args: any) => a(b(...args)))
}
  • 参数 : 函数fn1,fn2...
  • 返回值:一个合成函数

compose 函数的作用是传入一个函数数组,合成一个最终的函数;返回的结果会按照函数参数从右到左的顺序调用,如:

代码语言:javascript
复制
let func = compose(addExteranl,toUpperCase)
func('hello world')

func 执行会首先调用 toUpperCase,将调用结果作为参数传入 addExternal。根据数组中参数不同,可以组合不同的数据处理方式,使得更加灵活。

compose 实现原理

compose 是如何实现将不同函数组合的呢,在了解之前先看下 Array.reduce

arr.reduce(callback(accu, currentValue)),数组arr 中每个元素都会去执行提供的callback 元素,并将执行结果作为下次callback 的第一个参数,比如使用reduce 实现数组累加:

代码语言:javascript
复制
let arr = [1, 2, 3];
// accu 第一次如果没指定则为数组中的第一个元素,下次为上次callback 执行累加的结果,accu 取值依次为 1, 3
// currentValue 数组中的元素
let result = arr.reduce((accu, currentValue) => accu + currentValue)

在了解reduce 实现之后具体来看 compose 核心实现

代码语言:javascript
复制
return funcs.reduce((a, b) => (...args: any) => a(b(...args)))

首次调用时是 funcs[0], funcs[1] 返回一个函数 accu2 : (... args) => funcs[0](funcs[1](...args))

第二次调用是 accu2, funcs[3] 返回一个函数 accu3: (... args) => accu2(funcs[3])

最终合成 合成 f1(f2(f3(xxx)))实现从右左的调用

总结

本文主要讲解使用 reduce 巧妙的实现compose 的过程,compose 在高阶组件、插件实现以及数据合成处理等场景中经常会使用,提高代码的易用性。

参考资料

reduce 介绍:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

redux 中关于 compose 实现:https://github.com/reduxjs/redux/blob/master/src/compose.ts

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端知知 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • compose 初探
  • compose 实现原理
  • 总结
  • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档