如何在 redux-observable 中的史诗中执行 side-effect?

How to perform side-effect inside of an epic in redux-observable?

redux-observable 中,epics 正在接受操作流并返回新的操作流。在我的 use-case 中,我需要在调度某些操作后发送分析事件,然后什么也不做。

使用 redux-saga,我可以使用 takeEvery 收听该操作,并在 saga 函数中执行 side-effect:

function* saga() {
  yield takeEvery('SOME_ACTION', function*() {
    sendAnalytics();
  })
}

但是我怎样才能达到与 redux-observable 相同的效果呢?有很多副作用,不需要调度新操作,如初始化插件、日志记录、设置 cookie 等...

如果这两个库都是 anti-pattern,那么应该使用什么解决方案来实现这些效果?

绝对不是 anti-pattern 完全拥有一部 "read-only" 的史诗——但我想提醒的是,这通常是一个人正在做某事的迹象 less-than-idiomatic,但这不是这些情况之一。

在 Rx 中可能有很多方法可以实现这一点。这里有两个:

做 + 忽略元素

我认为这是它所做的最清楚的。 do 仅用于在不影响流的情况下为 next/error/complete 执行副作用(通常是日志记录)。然后我们使用 ignoreElements 来防止 SOME_ACTION 再次被调度(这会导致无限递归)。 See the rxjs docs for more info on these operators

const someEpic = action$ =>
  action$.ofType('SOME_ACTION')
    .do(() => sendAnalytics())
    .ignoreElements();

匿名 Observable

这是一个稍微 "lightweight" 的解决方案,因为它不使用 ofType 以外的任何运算符。不过,在你和你的队友对 RxJS 有扎实的掌握,特别是创建 custom/anonymous Observables 之前,我会警告不要使用这个。即不要编写您不理解的代码。

const someEpic = action$ =>
  new Observable(() =>
    action$.ofType('SOME_ACTION')
      .subscribe(() => sendAnalytics()) // subscription is returned so it can be cleaned up
  );

如果有人有时间 PR,这个用例将是对文档的食谱部分的一个很好的补充。


顺便说一句,这主要是一个 RxJS 问题,其中流恰好是动作。如果您在 RxJS 而不是 redux-observable 的上下文中搜索或表达您的问题,您可能会发现您会得到答案和更好的支持 long-term。几乎所有 redux-observable 问题实际上都是 RxJS 问题,这很好,因为知识是可以转移的!