我正在努力做一个"复杂的警报系统"在redux + redux-observable中。
要求是:
(我们可以重构直接使用SET_ALERT而不用REQUEST_ALERT直接在reducer中,但这不是问题)
我几乎实现了我的目标:
// generate the alert from the request
// you can ignore it if refactor with only REQUEST_ALERT
export const generateAlert$ = (action$) => {
return action$.ofType(REQUEST_ALERT)
.map(action => ({
type: SET_ALERT,
payload: generateAlertPayload(),
// just create action de type SET_ALERT and add an id
})
)
}
// the real important part
export const timeoutDismissAlert$ = (action$) => {
return action$.ofType(SET_ALERT)
.mergeMap(action =>
Rx.Observable.empty()
.concat(
// I wait for max delay and send the payload dismiss_alert
Rx.Observable.of(action)
.delay(maxDelay)
.map(({payload}) => ({type: DISMISS_ALERT, payload: payload.id}))
// I make a race with the user click vs the delay
.race(
action$.ofType(DISMISS_ALERT)
.skipWhile(({payload}) => payload !== action.payload.id)
.first()
.map(() => null)
)
)
// I would like to dispatch an action only if the delay win
.map((a) => a ? a : {type: "I_DONT_WANT"})
)
}
有没有办法在史诗结束时不发送动作?还是更好的Rxjs方法来实现它?
答案 0 :(得分:0)
对我而言,您似乎只想取消"取消"每当用户点击时,您的延迟观察结果就会被延迟观察,而takeUntil
可以为您提供帮助。
我想象所需的史诗看起来像这样:
// action creator
const dismissAlert = payload => ({ type: DISMISS_ALERT, payload });
// epic
const dismissAlert$ = action$ => {
return action$.ofType(SET_ALERT)
.mergeMap(action => {
const dismiss$ = action$.ofType(DISMISS_ALERT)
.filter(({ payload }) => payload === action.payload.id);
// the interesting part
return Rx.Observable.timer(maxDelay)
.mapTo(dismissAlert(action.payload.id))
.takeUntil(dismiss$);
});
};
现在嵌套的observable产生一个DISMISS_ALERT动作,如果用户在maxDelay
间隔过去之前点击,则不产生任何动作。