RxJS Observable Cancellation无效

时间:2018-02-06 18:42:21

标签: redux rxjs redux-observable

我在React / Redux中的一些实现有以下问题。

单击按钮后,将调用特定的redux操作,并在屏幕上显示带有通知的div。您可以通过单击该div上的(X)符号(另一个redux操作)来关闭此通知,或者通知将在5秒后自动关闭。单击(x)应取消自动操作。

 actions:

const OPEN = 'show_notification';
const CLOSE = 'close_notification';
const CLOSE_AUTO = 'close_auto';

function showNotification(data) {
     return {
        type: 'OPEN',
        data
     }
 }

function closeNotification(index) {
     return {
        type: 'CLOSE',
        index
     }
 }

function closeAuto() {
     return {
        type: 'CLOSE_AUTO'
     }
 }



epics:

import (...)

closeNotificationAuto = action$ => action
.filter(action => action.type === OPEN)
.mergeMap(action => action
.delay(5000)
.map( () => closeAuto)
.takeUntil(action$.ofType(CLOSE))
 }

无论如何,当屏幕上显示两个通知时,操作=== CLOSE正在关闭第一个,并取消另一个的延迟()。

没有发布我的整个代码,因为问题就在这里,在史诗中。无法实现解决方案:

当点击(x)时,特定通知已关闭,但另一个(例如3秒的时间)仍然可见,并在另外2秒后自动隐藏。

有任何帮助!

1 个答案:

答案 0 :(得分:1)

史诗中的代码是不完整的,所以它并不完全清楚(mergeMap内部会发生什么?)。但我确实看到了一个问题,即你的takeUntil位于顶级可观察链上,这意味着它不会取消那个特定的延迟,它也会停止听取任何行动。

相反,您需要在mergeMapswitchMap等内容中单独延迟和取消匹配的操作。这通常称为“隔离观察者链”。

这可能是这样的:

const closeNotificationAuto = action$ =>
  action$
    .ofType(OPEN)
    .mergeMap(action =>
      Observable.of(action)
        .delay(5000)
        .map(() => closeAuto())
        .takeUntil(action$.ofType(CLOSE))
    );

这个模式,然后过滤flatMap(mergeMap,switchMap等),就是你的大部分史诗的样子。

关于下面的评论,您可能希望在takeUntil通知程序中添加一个过滤器,以便仅采取以某种方式唯一标识它的CLOSE操作。

请参阅https://stackoverflow.com/a/48452283/1770633

const closeNotificationAuto = action$ =>
  action$
    .ofType(OPEN)
    .mergeMap(action =>
      Observable.of(action)
        .delay(5000)
        .map(() => closeAuto())
        .takeUntil(
          action$.ofType(CLOSE).filter(a => a.something === action.something)
        )
    );

如果每个都没有可用的某种唯一ID,则需要创建并包含一个。