多个HTTP请求,因为一个效果和多个动作

时间:2017-02-08 14:01:20

标签: angular effects ngrx

我有两个操作,a.loadb.load,并且在它们后面,注册了一个@effect来对c进行HTTP调用。但是,问题出现在页面加载时,调度了ab个操作,因此请求c两次。我需要对这两个操作做出反应的原因是因为在此页面上,ab可以更改,如果是,我需要执行请求以获取c的新值。

有没有办法处理/避免这种情况?也许我可以考虑取消效果中的任何先前请求?

感谢。

1 个答案:

答案 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请求,我不确定实现如何管理它们的取消 - 可能是他们的响应是简单地忽略了。