欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

Redux之compose

发布时间:2025/3/18 编程问答 47 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Redux之compose 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

前言

在前面的基础篇中我们讲解了createStore,bindActionCrearoes,combineReducers,在高级篇讲解了applyMiddleware,致此redux相关的5个API就剩下一个compose,之所以把compose单独写一篇文章的原因是因为是compose五个API里唯一一个能单独拿出来用的函数,就是函数式编程里常用的组合函数,和 redux 本身没有什么多大关系。

compose的作用

把复杂的多函数嵌套调用,组合成纯粹的函数调用,实现fn1(fn2(fn3(fn3(...args))))-->compose(fn1,fn2,fn3,fn4)(...args)这样单纯可读的函数调用方式

举例说明

let { compose } = require('redux'); function add1(str) {return '1' + str; } function add2(str) {return '2' + str; } function add3(str) {return '3' + str; } function add4(str) {return '4' + str; } let result = add1(add2(add3(add4('GuYan')))); console.log(result); // '1234GuYan' console.log(compose(add1,add2,add3,add4)('GuYan')); // '1234GuYan' 复制代码
  • 执行分析
    • 【1】componse执行返回一个函数
    • 【2】componse的参数为函数,返回的函数执行的时候实现了参数函数从右向左依次执行且每一个参数函数执行的结果为下一参数函数执行的入参,返回函数执行传入的参数作为第一次执行的参数函数的入参
  • 源码实现
export default function compose(...funcs){// 如果参数没传,我们自己内部实现一个函数返回if(funcs.lenth === 0){return arg => arg}// 如果传入的参数只有一个函数,直接返回该函数if(funv.length === 1){retrun funcs[0]}/*如果传入的参数为多个函数,我们为了实现执行分析的【2】中的从右向左依次执行且每一个参数函数执行的结果为下一参数函数执行的入参,不难想到我们数组中的遍历方法,没错就是reduce,但是reduce的遍历是从左向右的,而我们要实现的是从右向左执行,所以我们选用reduceRight来实现*/return funcs.reduceRight((a,b)=>(...args)=>b(a(...args))); } 复制代码

相信大家一定可以读懂前面的源码实现了(如果有不明白的地方欢迎下方留言),但是细心的朋友们会发现真正的源码的实现并不是用reduceRight而是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))) } 复制代码

上面代码片段是我直接从源码中拷贝过来的,为了方便讲解我们将箭头函数修改成普通函数形式,结果如下

export default function compose(...funcs) {// 前两种我就不复述了return funcs.reduce(function (a,b) {return function (...args) {return a(b(...args))}}) } 复制代码
  • 结合示例
    • 第一次迭代
      • 参数:add1,add2
      • 返回function fn1(...args1){return add1(add2(...args1))}
    • 第二次迭代
      • 参数:function fn1(...args1){return add1(add2(...args1))},add3
      • 返回:function fn2(...args2){return (function fn1(...args1){return add1(add2(...args1))})(add3(...args2))}
      function fn2(...args2) {return (function fn1(...args1) {return add1(add2(...args1))})(add3(...args2)) } /* 源代码执行的时候返回的是a执行传入b执行返回的结构, 此时a是function fn1(...args1){return add1(add2(...args1))},b是add3; 所以我用一个让function fn1(...args1){return add1(add2(...args1))}自执行传入add3(...args2), 需要注意的是此时函数中的args1就是add3(...args2) */ 复制代码
    • 第三次迭代
      • 参数:function fn2(...args2){return (function fn1(...args1){return add1(add2(...args1))})(add3(...args2))},add4
      • 返回:function fn3(...args3) {return (function fn2(...args2) {return (function fn1(...args1) {return add1(add2(...args1))})(add3(...args2))})(add4(...args3))}
      function fn3(...args3) {return (function fn2(...args2) {return (function fn1(...args1) {return add1(add2(...args1))})(add3(...args2))})(add4(...args3))} /* 此时a是function fn2(...args2){return (function fn1(...args1){return add1(add2(...args1))})(add3(...args2))},b是add4(...args3);* 如第二次迭代一样我们依据用一个自执行函数包裹a,且传入参数`add4(...args3)`* 需要注意的是此时函数中的args2就是add4(...args3)*/ 复制代码
第几次循环a的值b的值返回的值
第一次add1add2(...args1)=>(add1(add2(...args1)))
第二次(...args1)=>(add1(add2(...args1)))add3(...args2)=>((...args1)=>(add1(add2(...args1))))(add3(...args2))即(...args2)=>add1(add2(add3(...args2)))
第三次(...args)=>(add1(add2(add3(...args))))add4(...args3)=>((...args2)=>(add1(add2(add3(...args)))))(add4(...args3))即(...args)=>add1(add2(add3(add4(...args))))

转载于:https://juejin.im/post/5ce973df51882521d51ec73b

总结

以上是生活随笔为你收集整理的Redux之compose的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。