一个效果多个动作导致多次HTTP请求

Multiple HTTP requests because of one effect and multiple actions

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

有什么办法可以解决/避免这种情况吗?也许我可以考虑取消效果内的任何先前请求?

谢谢。

您应该能够使用 throttle operator 解决问题 - 它接受一个函数,该函数 returns 是一个可观察对象,并且在该可观察对象发出之前,源发出的任何值都是 throttled/ignored.

如果您传递 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 }))
    );

如果您以这种方式将 throttle 与您的 HTTP-based 效果一起使用,那么如果有待处理的 HTTP 请求,它会看到任何触发该效果的操作都会被忽略。因此,如果那是您正在寻找的行为,它应该可以解决您的问题。

关于您的评论,如果您希望处理最后一个间隔很近的操作,您可以考虑使用 auditTime operator - 它将等待指定的持续时间,然后发出最近收到的值:

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