减速器和中间件有啥区别?

Posted

技术标签:

【中文标题】减速器和中间件有啥区别?【英文标题】:What is the difference between a reducer and middleware?减速器和中间件有什么区别? 【发布时间】:2017-12-27 22:40:18 【问题描述】:

我在理解 reducer 和中间件之间的应用差异时遇到了一些麻烦。许多网站描述了中间件,甚至给出了精确的定义:

它在调度一个动作和它到达reducer之间提供了一个第三方扩展点。

或者:

中间件是通过组合功能来创建的,这些功能包装了单独的横切关注点,这些关注点不是您的主要执行任务的一部分。

但从这些我的理解是,不同,只是没有什么。据我所知,区别在于一个人采取行动并将该行动传递下去,而另一个人采取行动和状态并“将状态传递下去”。但是您仍然可以访问中间件中的商店。所以 store 和 action 都经过中间件,然后是 reducer。因此,reducer 可以执行日志记录。

虽然日志似乎是中间件的明显应用,但还有更多模棱两可的例子。例如,在模块中编写一些简单的身份验证,您可以使用中间件函数来执行用户发送的操作并确定他们的身份验证级别:

import  getAuthLevel  from './auth';

export default store => next => action => 
  return next(...action, auth: getAuthLevel(action.clientId));

你可能有很多这样的用户:


users: [
  clientId: 'bobsUnqiueClientId',
  user: 'Bob',
  password: 'ilikecats',
  authlevel: 'OVERLORD'
, 
  clientId: 'anotherUniqueClientId',
  user: 'Alice',
  password: 'boblikescats',
  authlevel: 'MINION'
]

那么您可能有对应于不同身份验证级别的操作。您可以使用中间件对其进行映射,但您需要了解有关正在执行的操作的更多具体细节,并且看起来更像是更多“与执行相关”的代码。但是,它不需要了解有关状态的任何信息。它只需要决定将哪些操作转发给减速器。

所以?这样的代码会放在减速器还是中间件中?谁能提供其他具体示例来阐明两者之间的区别?

【问题讨论】:

reducer 的一个定义:redux.js.org/docs/basics/Reducers.html。我不完全确定这是一个始终具有完全相同含义的行业标准术语,因此它可能取决于上下文或使用它的人。 【参考方案1】:

reducer 是一个函数,它将你的状态的一部分和当前调度的动作作为参数,并返回一个更新的状态。多个 reducer 函数可以组合在一起形成您传递给 createStore()root reducer 函数。 Reducers 应该是“纯函数”,没有“副作用”。这意味着没有 AJAX 调用,没有调度操作,并且(理论上)没有日志记录 - 只是 (state, action) => newState。 (现在,您可以登录reducer,该代码可以正常工作,但原则上这仍然不是reducer应该做的事情。)

中间件是一段代码,它包裹着商店的dispatch 函数。多个中间件可以通过applyMiddleware() 增强器变成一个管道。当一个动作被调度时,它将依次通过管道中的每个中间件。每个中间件都可以对动作做任何它想做的事情:记录它、延迟它、修改它、分派其他东西,或者只是将它传递到管道中。最终,最后一个中间件将操作传递给实际的 store.dispatch() 函数,该函数调用根 reducer 并启动状态更新逻辑。

所以是的,一般来说,中间件提供了一个地方来执行与操作相关的集中逻辑,例如授权检查或日志记录。

您可能想阅读 Redux 文档中的 Structuring Reducers 部分,以获取有关 reducer 如何工作和组织的更多示例,我的 React/Redux links list 有讨论 Redux middleware 和 reducer usage 的文章部分。

【讨论】:

说得很好!

以上是关于减速器和中间件有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

控制器和中间件有啥区别

API、框架和中间件有啥区别? [关闭]

Connect/Express 中的“session”和“cookieSession”中间件有啥区别?

文档中间件、模型中间件、聚合中间件、查询中间件有啥区别?

文档中间件、模型中间件、聚合中间件、查询中间件有啥区别?

Scala 中间件选择之间有啥区别?