lihuakkk/blog

Redux源码分析 —— compose实现

lihuakkk opened this issue · 0 comments

Redux源码中的compose函数分析

关于Redux源码和**分析已经有很多很好的文章,在这里只讨论其中的一个工具函数,compose。Redux ApplyMiddleware通过compose函数将中间件串联起来。

compose的定义

将多个单参数的函数从右到左串联在一起,前一个函数的返回值做后一个函数的参数,最右边的函数可以有多个参数。

compose(f, g, h) = (...args) => f(g(h(...args)))

compose的实现

源码中compose的实现非常简洁,核心代码更是只有一行。

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(f, g, h, j) = compose(compose(f, g), h, j);
compose(f, g, h, j) = compose(f, compose(g, h, j));

源码中的实现是利用第一个等式,每次取最前面的两个函数compose,返回一个新的函数跟下一个函数compose。

也可以使用第二个等式的**,先将除了第一个函数之外的所有函数compose,返回的新函数再跟第一个函数compose,实现如下:

function compose2(...funcs) {
  const [a, ...funcs2] = funcs;
  
  if(funcs.length === 0) {
    return arg => arg;
  }
  
  if(funcs.length === 1) {
    return funcs[0];
  }
  
  if(funcs.length === 2) {
    const [b] = funcs2;
    return (...args) => a(b(...args));
  }
  
  return compose2(...[a, compose2(...funcs2)])
}
    

如果有更好的实现,欢迎讨论

THE END