如何在redux observable中重新执行操作?

如何在redux observable中重新执行操作?,redux,observable,redux-observable,Redux,Observable,Redux Observable,例如,此代码 当单击“取消”按钮后操作为“takeUntil”时,则该操作无效。为什么取消后会延迟1秒,更改不会再次发生。问题在于对RxJS的工作原理有一个微妙但关键的误解——但不用担心,这是很常见的 举个例子: const pingEpic=action$=> 类型的操作$(PING) .延迟(1000) .mapTo({type:PONG}) .takeUntil(类型为(取消)的动作$); 此epic的行为可以描述为过滤所有不匹配类型的操作PING。当一个动作匹配时,等待1000毫秒,然

例如,此代码


当单击“取消”按钮后操作为“takeUntil”时,则该操作无效。为什么取消后会延迟1秒,更改不会再次发生。

问题在于对RxJS的工作原理有一个微妙但关键的误解——但不用担心,这是很常见的

举个例子:

const pingEpic=action$=>
类型的操作$(PING)
.延迟(1000)
.mapTo({type:PONG})
.takeUntil(类型为(取消)的动作$);
此epic的行为可以描述为过滤所有不匹配类型的操作
PING
。当一个动作匹配时,等待1000毫秒,然后将该动作映射到另一个动作
{type:PONG}
,该动作将被发出,然后由redux observable发送。如果在应用程序运行期间的任何时间,有人发送类型为“取消”的操作,则从源位置取消订阅,这意味着整个链将取消订阅,从而终止epic

如果您是强制性地这样做的话,那么看看它的外观可能会有所帮助:

const pingEpic=action$=>{
返回新的可观察接收(观察者=>{
log(“[pingEpic]subscribe”);
让定时器;
const subscription=action$.subscripte(action=>{
console.log('[pingEpic]接收到的操作:'+action.type);
//当有人发送取消,我们完全停止收听!
如果(action.type==取消){
observer.complete();
返回;
}
如果(action.type==PING){
计时器=设置超时(()=>{
常量输出={type:PONG};
下一步(输出);
}, 1000);
}
});
返回{
退订{
log(“[pingEpic]unsubscribe”);
清除超时(计时器);
订阅。取消订阅();
}
};
});
};
您可以在此处使用假商店运行此代码:


相反,您通常要做的是将您希望取消的订户链与假定无限期侦听的顶级链隔离。虽然您的示例(根据文档进行了修改)是人为的,但让我们先来看一下

在这里,我们使用操作符来执行匹配操作,并映射到另一个独立的可观察链

演示:

const pingEpic=action$=>
类型的操作$(PING)
.mergeMap(()=>
可观察计时器(1000)
.takeUntil(类型的动作$(取消))
.mapTo({type:PONG})
);
我们通常等待1000毫秒,然后将它发出的值(恰好是数字零,但这在这里并不重要)映射到我们的
PONG
操作。我们还说,我们希望从计时器源“获取”,直到它正常完成或接收到类型为
CANCEL
的操作

这将隔离链,因为
mergeMap
将继续订阅您返回的可观察对象,直到它出错或完成。但当这种情况发生时,它本身并不会停止订阅您应用它的源代码;在本例中,类型(PING)的
操作$

一个更真实的例子是

在这里,我们将.takeUntil()放在.mergeMap()中,但放在AJAX调用之后;这一点很重要,因为我们只想取消AJAX请求,而不是阻止Epic监听任何未来的操作

const fetchUserEpic=action$=>
类型的操作$(获取用户)
.mergeMap(操作=>
getJSON(`/api/users/${action.payload}`)
.map(fetchUserCompleted)
.takeUntil(类型的动作$。(获取用户\u取消))
);
这一切听起来可能令人困惑,但就像最强大的东西一样,一旦你得到它,它就会变得直观。Ben Lesh出色地解释了可观测数据是如何工作的,包括讨论了操作符是如何构成可观测数据链的,甚至还讨论了如何隔离用户链。即使谈话是在AngularConnect进行的,也不是针对角度的



另一方面,重要的是要注意,你的史诗不会吞没或阻止动作到达还原器,例如,当你将一个传入动作映射到另一个不同的动作时。事实上,当你的史诗收到一个行动,它已经通过你的还原。把你的epics想象成一个旁站程序,它可以监听你的应用程序的动作流,但不能阻止正常的redux事件发生,它只能发出新的动作。

问题是对RxJS如何工作的一个微妙但关键的误解——但不用担心,这是很常见的

举个例子:

const pingEpic=action$=>
类型的操作$(PING)
.延迟(1000)
.mapTo({type:PONG})
.takeUntil(类型为(取消)的动作$);
此epic的行为可以描述为过滤所有不匹配类型的操作
PING
。当一个动作匹配时,等待1000毫秒,然后将该动作映射到另一个动作
{type:PONG}
,该动作将被发出,然后由redux observable发送。如果在应用程序运行期间的任何时间,有人发送类型为“取消”的操作,则从源位置取消订阅,这意味着整个链将取消订阅,从而终止epic

如果您是强制性地这样做的话,那么看看它的外观可能会有所帮助:

const pingEpic=action$=>{
返回新的可观察接收(观察者=>{
log(“[pingEpic]subscribe”);
让定时器;
const subscription=action$.subscripte(action=>{
console.log('[pingEpic]接收到的操作:'+action.type);
//当有人发送取消,我们完全停止收听!
如果(action.type==取消){
observer.complete();
返回;
}
如果(action.type==PING){
计时器=设置超时(()=>{
常量输出={type:PONG};
下一步(输出);
}, 1000);
}
});
返回{
退订
const pingEpic = action$ =>
  action$.ofType(PING)
    .delay(1000) // Asynchronously wait 1000ms then continue
    .mapTo({ type: PONG })
    .takeUntil(action$.ofType(CANCEL));