例如此代码jsbin示例
const pingEpic = action$ =>
action$.ofType(PING)
.delay(1000) // Asynchronously wait 1000ms then continue
.mapTo({ type: PONG })
.takeUntil(action$.ofType(CANCEL));
单击取消按钮后,如果操作为“ takeUntil”,则此操作无效。为什么取消后延迟1秒钟,并且更改没有再次发生。
问题是对RxJS的工作方式的细微但关键的误解-但不要担心,这很常见。
因此,以您的示例为例:
const pingEpic = action$ =>
action$.ofType(PING)
.delay(1000)
.mapTo({ type: PONG })
.takeUntil(action$.ofType(CANCEL));
该史诗的行为可以描述为过滤所有不匹配type的动作PING
。当一个动作匹配时,等待1000毫秒,然后将该动作映射到另一个动作{ type: PONG }
,该动作将被发出,然后由redux-observable调度。如果在任何而应用程序正在运行有人调度类型的动作时间CANCEL
,然后退订从源,这意味着这整个链将退订,终止史诗。
如果您必须执行此操作,则查看它的外观可能会有所帮助:
const pingEpic = action$ => {
return new Rx.Observable(observer => {
console.log('[pingEpic] subscribe');
let timer;
const subscription = action$.subscribe(action => {
console.log('[pingEpic] received action: ' + action.type);
// When anyone dispatches CANCEL, we stop listening entirely!
if (action.type === CANCEL) {
observer.complete();
return;
}
if (action.type === PING) {
timer = setTimeout(() => {
const output = { type: PONG };
observer.next(output);
}, 1000);
}
});
return {
unsubscribe() {
console.log('[pingEpic] unsubscribe');
clearTimeout(timer);
subscription.unsubscribe();
}
};
});
};
您可以在以下的伪造商店中运行此代码:http : //jsbin.com/zeqasih/edit?js,console
取而代之的是,您通常要做的是将您希望可取消的订户链与假定无限期监听的顶级链隔离开。尽管您的示例(从文档中进行了修改)是人为设计的,但让我们先对其进行遍历。
在这里,我们使用mergeMap运算符让我们执行匹配的动作并将其映射到另一个单独的可观察链。
演示:http : //jsbin.com/nofato/edit?js,输出
const pingEpic = action$ =>
action$.ofType(PING)
.mergeMap(() =>
Observable.timer(1000)
.takeUntil(action$.ofType(CANCEL))
.mapTo({ type: PONG })
);
我们Observable.timer
通常要等待1000毫秒,然后将它发出的值(恰好是数字零,但这在这里并不重要)映射到我们的PONG
动作。我们还说我们要从计时器源中“获取”,直到它正常完成或收到type的操作为止CANCEL
。
这将隔离链,因为mergeMap
它将继续订阅您返回的可观察对象,直到它出错或完成为止。但是,一旦发生这种情况,它本身并不会停止订阅您将其应用到的源;的action$.ofType(PING)
在这个例子中。
一个更真实的示例在Cancellation部分的redux-observable文档中
在这里,我们将.takeUntil()放在.mergeMap()内部,但是放在我们的AJAX调用之后;这很重要,因为我们只想取消AJAX请求,而不是阻止Epic监听将来的任何动作。
const fetchUserEpic = action$ =>
action$.ofType(FETCH_USER)
.mergeMap(action =>
ajax.getJSON(`/api/users/${action.payload}`)
.map(fetchUserFulfilled)
.takeUntil(action$.ofType(FETCH_USER_CANCELLED))
);
这一切听起来可能令人困惑,但是就像大多数强大的功能一样,一旦您掌握了它,它将变得直观。Ben Lesh在最近的演讲中很好地解释了Observables的工作原理,包括讨论了运营商如何构成Observables链,甚至是隔离订户链。即使讨论是在AngularConnect上进行的,也不是特定于Angular的。
顺便说一句,重要的是要注意您的史诗不会吞咽或阻止动作到达减速器,例如,当您将传入动作映射到另一个不同动作时。实际上,当您的史诗收到一个动作时,它已经通过了还原器。将您的史诗看作是旁听程序,它监听应用程序动作的流,但不能阻止正常的还原操作发生,它只能发出新动作。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句