乐闻世界logo
搜索文章和话题

Redux 中的 compose 函数的作用是什么?

7 个月前提问
3 个月前修改
浏览次数47

2个答案

1
2

compose 函数在 Redux 中的主要作用是实现从右到左的函数组合。在 Redux 的上下文中,它通常用于中间件、增强器(enhancers)或者将多个函数组合成一个函数的场景。

函数组合是一种在函数式编程中常见的概念,它允许你把多个函数组合成一个单一的函数。组合后的函数将从右到左执行各个单独的函数,这意味着最右边的函数的输出将成为右边邻近函数的输入,以此类推,直到最左边的函数。

compose 函数的签名大概如下所示:

javascript
compose(...functions)

每个 function 都是将接收一个值然后返回一个值的函数。当你调用 compose 生成的函数时,你给它传递的参数将会被最右边的函数接收,并且每个函数的输出都将成为下一个函数的输入。

例如,如果你有这样几个函数:

javascript
function print(input) { console.log(input); return input; } function multiplyBy5(input) { return input * 5; } function subtract2(input) { return input - 2; }

如果你想要创建一个新函数,这个新函数能够先执行 subtract2,然后执行 multiplyBy5,最后执行 print,你可以使用 compose

javascript
const composedFunction = compose(print, multiplyBy5, subtract2);

当你调用 composedFunction(10) 时,将会按照以下的顺序执行操作:

  1. subtract2(10) 会先执行,返回 8
  2. multiplyBy5(8) 会拿到 8 并返回 40
  3. print(40) 拿到 40 并将其打印出来。

在 Redux 中,compose 函数常常用于中间件的组合。例如,在配置 Redux store 时,你可能需要将多个中间件和 Redux DevTools 扩展组合起来,以增强 createStore。这通常是通过 compose 函数来完成的。

javascript
import { createStore, applyMiddleware, compose } from 'redux'; import thunk from 'redux-thunk'; import rootReducer from './reducers'; const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; const store = createStore( rootReducer, composeEnhancers( applyMiddleware(thunk) // 可以在这里添加更多的中间件 ) );

在这个场景中,composeEnhancers 利用了 Redux DevTools 扩展的能力,并且与 applyMiddleware 结合,将 thunk 中间件应用到了 store 的创建过程中。这样,你就能够在开发过程中更方便地调试异步操作以及其他可能会修改状态的操作。

2024年6月29日 12:07 回复

提高可读性和便利性是使用 compose 的主要优点。

当您想要将多个存储增强器传递到存储时,可以使用_Compose 。存储增强器是高阶函数,可为存储添加一些额外的功能。默认情况下,Redux 提供的唯一存储增强器是_applyMiddleware,但是还有许多其他可用的增强器。

存储增强器是高阶函数

什么是高阶函数?摘自Haskell 文档

高阶函数可以将函数作为参数并返回函数作为返回值。执行其中任一操作的函数称为高阶函数

来自 Redux 文档:

compose 所做的只是让您编写深度嵌套的函数转换,而不会导致代码向右漂移。不要给予它太多的信任!

因此,当我们链接高阶函数(存储增强器)而不必编写时

shell
func1(func2(func3(func4))))

我们可以写

shell
compose(func1, func2, func3, func4)

这两行代码做同样的事情。只是语法不同。

终极版示例

Redux 文档来看,如果我们不使用_compose,_我们就会有

shell
finalCreateStore = applyMiddleware(middleware)( require('redux-devtools').devTools()( require('redux-devtools').persistState( window.location.href.match(/[?&]debug_session=([^&]+)\b/) )() ) )(createStore);

而如果我们使用_compose_

shell
finalCreateStore = compose( applyMiddleware(...middleware), require('redux-devtools').devTools(), require('redux-devtools').persistState( window.location.href.match(/[?&]debug_session=([^&]+)\b/) ) )(createStore);

要了解有关 Redux 撰写功能的更多信息,请单击此处

检查原始compose源代码也可能很有用,因为它在纯 JavaScript 中只有 10 个 loc。

2024年6月29日 12:07 回复

你的答案