javascript - recompose 库中的 Compose 方法

标签 javascript reactjs functional-programming reduce higher-order-functions

我正在查看@acdlite 编写的重组库中的compose 函数来为高阶组件组合边界条件,这就是 compose 函数的样子

const compose = (...funcs) => funcs.reduce((a, b) => (...args) => a(b(...args)), arg =>参数);

不过,我试过了Eric-Elliott的一种组合方法,来自 https://medium.com/javascript-scene/reduce-composing-software-fe22f0c39a1d ,具体来说就是这段代码。

const compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x);

我试过在我的 React 组件中使用这两种变体,

const ListWithConditionalRendering = compose(
  withLoadingIndicator,
  withDataNull,
  withListEmpty
)(Users);

而且它们似乎都工作正常。我无法理解上述功能的工作方式是否有任何差异,如果有,它们是什么。

最佳答案

对于非常小众的场景,有一些差异可能有助于了解。

第一个预组合一个函数,这意味着它调用reduce()什么时候组成而不是什么时候被调用。相反,第二种方法返回一个调用 reduceRight() 的作用域函数。当它被调用时,而不是它被组合时。

第一个方法接受数组中最后一个函数的多个参数,而第二个方法只接受一个参数:

const compose1 = (...funcs) => funcs.reduce((a, b) => (...args) => a(b(...args)), arg => arg);
const compose2 = (...fns) => x => fns.reduceRight((v, f) => f(v), x);

const f = s => (...args) => (console.log('function', s, 'length', args.length), args);

compose1(f(1), f(2), f(3))(1, 2, 3);
compose2(f(4), f(5), f(6))(1, 2, 3);

如果函数数组非常大,因为它是预组合的,第一种方法可能会导致堆栈溢出,而第二种方法(相对)堆栈安全:

const compose1 = (...funcs) => funcs.reduce((a, b) => (...args) => a(b(...args)), arg => arg);
const compose2 = (...fns) => x => fns.reduceRight((v, f) => f(v), x);

const f = v => v;

try {
  compose1.apply(null, Array.from({ length: 1e5 }, () => f))();
  console.log('1 is safe');
} catch (e) {
  console.log('1 failed');
}

try {
  compose2.apply(null, Array.from({ length: 1e5 }, () => f))();
  console.log('2 is safe');
} catch (e) {
  console.log('2 failed');
}

†如果...fns,第二种方法仍然会导致堆栈溢出。太大因为arguments也在栈上分配。

关于javascript - recompose 库中的 Compose 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53924558/

相关文章:

javascript - 如何记住方法是否改变了原始数组?

javascript - ionic 2 - 获取 window.scrollTop

javascript - 我尝试使用 Bootstrap 通过单击图像来实现模式,但它不起作用

javascript - 使用 Reactjs Chartjs 和 axios 创建图表

haskell - 返回值的模式匹配

types - OCaml 类型推断算法是如何工作的?

javascript - 将支付网关与 angularjs 应用程序和 spring 后端集成

reactjs - 从单个文件导出的 Material UI v4 makeStyles 不会在刷新时保留样式

typescript - 在 React、Typescript 中获取查询参数

Haskell:理解广义代数数据类型