RxJS Observable 取消不起作用
RxJS Observable Cancellation doesn work
我在 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 是关闭第一个通知,并取消另一个通知的 delay() 。
没有发布我的全部代码,因为问题出在 epics 中。无法设法实现解决方案:
当单击 (x) 时,特定通知关闭,但另一个通知(时间为 3 秒)仍然可见,并在 2 秒后自动隐藏。
感谢您的帮助!
史诗中的代码不完整,所以不是很清楚(mergeMap内部发生了什么?)。但我确实看到了一个问题,那就是你的 takeUntil
在 top-level 可观察链上,这意味着它不仅会取消那个特定的延迟,它还会停止监听任何动作。
相反,您需要在 mergeMap
、switchMap
等内容中单独延迟和取消匹配的操作。这通常称为 "isolating your observer chains"。
这可能是这样的:
const closeNotificationAuto = action$ =>
action$
.ofType(OPEN)
.mergeMap(action =>
Observable.of(action)
.delay(5000)
.map(() => closeAuto())
.takeUntil(action$.ofType(CLOSE))
);
这种模式,先过滤然后 flatMap(mergeMap、switchMap 等),是您 epics 的大部分外观。
关于您在下面的评论,听起来您想向 takeUntil
通知程序添加一个过滤器,以仅执行以某种方式唯一标识它的 CLOSE 操作。
见
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,您将需要创建并包含一个。
我在 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 是关闭第一个通知,并取消另一个通知的 delay() 。
没有发布我的全部代码,因为问题出在 epics 中。无法设法实现解决方案:
当单击 (x) 时,特定通知关闭,但另一个通知(时间为 3 秒)仍然可见,并在 2 秒后自动隐藏。
感谢您的帮助!
史诗中的代码不完整,所以不是很清楚(mergeMap内部发生了什么?)。但我确实看到了一个问题,那就是你的 takeUntil
在 top-level 可观察链上,这意味着它不仅会取消那个特定的延迟,它还会停止监听任何动作。
相反,您需要在 mergeMap
、switchMap
等内容中单独延迟和取消匹配的操作。这通常称为 "isolating your observer chains"。
这可能是这样的:
const closeNotificationAuto = action$ =>
action$
.ofType(OPEN)
.mergeMap(action =>
Observable.of(action)
.delay(5000)
.map(() => closeAuto())
.takeUntil(action$.ofType(CLOSE))
);
这种模式,先过滤然后 flatMap(mergeMap、switchMap 等),是您 epics 的大部分外观。
关于您在下面的评论,听起来您想向 takeUntil
通知程序添加一个过滤器,以仅执行以某种方式唯一标识它的 CLOSE 操作。
见
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,您将需要创建并包含一个。