Javascript 如何在redux observable中执行epic内部的副作用?

Javascript 如何在redux observable中执行epic内部的副作用?,javascript,redux,rxjs,redux-saga,redux-observable,Javascript,Redux,Rxjs,Redux Saga,Redux Observable,在redux observable中,epics接受动作流并返回新动作流。在我的用例中,我需要在一些动作被分派之后发送分析事件,之后什么也不做 使用redux saga,我只需使用takeEvery收听该操作,并在saga函数中执行一个副作用: function* saga() { yield takeEvery('SOME_ACTION', function*() { sendAnalytics(); }) } 但是如何使用redux observable实现同样的效果呢?还

在redux observable中,epics接受动作流并返回新动作流。在我的用例中,我需要在一些动作被分派之后发送分析事件,之后什么也不做

使用
redux saga
,我只需使用
takeEvery
收听该操作,并在saga函数中执行一个副作用:

function* saga() {
  yield takeEvery('SOME_ACTION', function*() {
    sendAnalytics();
  })
}
但是如何使用
redux observable
实现同样的效果呢?还有很多副作用,不需要分派新的操作,比如初始化插件、记录日志、设置cookies等等


如果这两个库都是反模式的,那么对于这类效果应该使用什么解决方案呢?

绝对不是一个完全反模式,即有一个“只读”的epic——但我想提醒的是,这通常是一个人在做一些不惯用的事情的迹象,但这不是其中之一

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

do+忽略元素 我认为这是最清楚的
do
仅用于在不影响流的情况下对next/error/complete执行副作用(通常记录)。然后,我们使用
ignoreElements
来防止
某些动作
再次被调度(这将导致无限递归)

匿名可观察 这是一个更“轻量级”的解决方案,因为它不使用除类型之外的任何操作符。不过,在你和你的队友对RxJS有了扎实的掌握,尤其是在创建自定义/匿名观测之前,我会提醒你不要使用这个。i、 不要写你不懂的代码

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

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



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

我没有使用过
redux saga
redux observable
,但我只是通过调用
mapDispatchToProps
中的分析模块来实现跟踪的这种特殊副作用,我认为这是一个合法的地方。因此,在调用
dispatch
之前或之后,您只需执行类似于
googleAnalytics.trackEvent(…)
的操作。谢谢,但在我看来,
mapDispatchToProps
函数不是执行副作用的正确位置我想说,“我真的很感谢你为清晰、完整地回答redux可观察问题所付出的思考和努力,@jayphelps!”!我不仅学习了redux observable,还学习了有价值的RxJS技巧。所以,谢谢!为什么使用ignoreElements而不是NEVER?哪一个更好?@Fen1kz
never()
是一个静态可观察工厂——它返回一个从未发出、从未完成、从未出错的源可观察工厂<另一方面,code>ignoreElements()是一个操作符——这意味着它对另一个源可观测对象进行操作,而不是作为静态生产者本身——当应用于一个可观测对象时,它将忽略源可观测对象发出的任何值。所以不一样:)
ignoreElements()
不会忽略错误/完成。
const someEpic = action$ =>
  new Observable(() =>
    action$.ofType('SOME_ACTION')
      .subscribe(() => sendAnalytics()) // subscription is returned so it can be cleaned up
  );