我有两个操作,a.load
和b.load
,并且在它们后面,注册了一个@effect来对c
进行HTTP调用。但是,问题出现在页面加载时,调度了a
和b
个操作,因此请求c
两次。我需要对这两个操作做出反应的原因是因为在此页面上,a
或b
可以更改,如果是,我需要执行请求以获取c
的新值。
有没有办法处理/避免这种情况?也许我可以考虑取消效果中的任何先前请求?
感谢。
答案 0 :(得分:1)
你应该能够使用throttle
operator来解决问题 - 它接受一个返回一个observable的函数,并且在该observable发出之前,源被发出的任何值都被限制/忽略。
如果您传递效果本身throttle
,则在处理慢速请求时收到的任何操作都将被忽略。例如:
import 'rxjs/add/operator/throttle';
@Effect()
someEffect = this.actions
.ofType(SOME_REQUEST)
.throttle(() => this.someEffect)
.switchMap((action) => someSlowRequest(action.payload)
.map((result) => ({ type: SOME_RESPONSE, payload: result }))
.catch((error) => Observable.of({ type: SOME_ERROR, payload: error }))
);
如果以这种方式对基于HTTP的效果使用throttle
,则会在有待处理的HTTP请求时看到触发该效果的所有操作都被忽略。所以,如果这是你正在寻求的行为,它应该解决你的问题。
关于您的评论,如果您希望处理最后一个紧密间隔的操作,您可以考虑使用auditTime
operator - 它将等待指定的持续时间,然后将发出最近收到的值:< / p>
import 'rxjs/add/operator/auditTime';
@Effect()
someEffect = this.actions
.ofType(SOME_REQUEST)
.auditTime(100)
.switchMap((action) => someSlowRequest(action.payload)
.map((result) => ({ type: SOME_RESPONSE, payload: result }))
.catch((error) => Observable.of({ type: SOME_ERROR, payload: error }))
);
或者,您可以依赖switchMap
运算符 - 在收到新值时取消订阅。但是,我的理解是ngrx
动作是同步调度的,因此可能会为每个动作发出HTTP请求,我不确定实现如何管理它们的取消 - 可能是他们的响应是简单地忽略了。