一个效果多个动作导致多次HTTP请求
Multiple HTTP requests because of one effect and multiple actions
我有两个操作,a.load
和 b.load
,在它们的后面,注册了一个 @effect 来为 c
执行 HTTP 调用。但是,问题出现在页面加载时,a
和 b
操作都被分派,因此 c
被请求了两次。我需要对这两个操作做出反应的原因是因为在此页面上,a
或 b
可以更改,如果是这样,我需要执行请求以获取 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 请求,我不确定实现将如何管理它们的取消 - 可能是它们的响应是简直被忽略了。
我有两个操作,a.load
和 b.load
,在它们的后面,注册了一个 @effect 来为 c
执行 HTTP 调用。但是,问题出现在页面加载时,a
和 b
操作都被分派,因此 c
被请求了两次。我需要对这两个操作做出反应的原因是因为在此页面上,a
或 b
可以更改,如果是这样,我需要执行请求以获取 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 请求,我不确定实现将如何管理它们的取消 - 可能是它们的响应是简直被忽略了。