【发布时间】:2019-12-19 21:03:22
【问题描述】:
情况如下:
我必须进行 HTTP 调用来检索 ID。使用此 ID,我将创建第二个端点以进行第二次 HTTP 调用。
我的第一个动作是FirstEntity.searchRequest。效果 - 在发出 HTTP 请求后 - 将映射其成功并创建操作 FirstEntity.searchSuccess。之后,我想在这个准确的时刻继续SecondEntity.searchRequest。
我想出了两个解决方案,但它们并不让我满意。
第一个解决方案:
[...]
switchMap(([_, endpointGenerator, { id}]) =>
this.httpClient
.get<ApiFirstEntitySearchSuccess>(`${this.apiBaseUrl}${endpointGenerator(id)}`, {
headers: new HttpHeaders(this.httpHeadersConfig),
params: {}
})
.pipe(
takeUntil(
this.actions$.pipe(
ofType(ApiFirstEntityActions.searchRequest),
skip(1)
)
),
map((success) => ApiFirstEntityActions.searchSuccess({ success })),
catchError((failure) => of(ApiFirstEntityActions.searchFailure({ failure })))
)
),
tap(() => ApiSecondEntityActions.searchRequest()),
[...]
这个将在switchMap() 之后tap()。它看起来不错,应该可以工作,只是即使第一次 HTTP 调用失败并且被catchError 捕获,它也会继续进行。
第二种解决方案:
[...]
switchMap(([_, endpointGenerator, { id}]) =>
this.httpClient
.get<ApiFirstEntitySearchSuccess>(`${this.apiBaseUrl}${endpointGenerator(id)}`, {
headers: new HttpHeaders(this.httpHeadersConfig),
params: {}
})
.pipe(
takeUntil(
this.actions$.pipe(
ofType(ApiFirstEntityActions.searchRequest),
skip(1)
)
),
mergeMap((success) => {
return [ApiFirstEntityActions.searchSuccess({ success }), ApiSecondEntityActions.searchRequest()];
}),
catchError((failure) => of(ApiFirstEntityActions.searchFailure({ failure })))
)
),
[...]
在这里,只有当第一个实体操作通过传递一系列操作而成功时,我才会创建第二个实体操作。然而,这两个动作将同时进行(我猜?),因此第二个动作可能会在填充之前尝试从状态中获取 ID。
那么这里最好的解决方案是什么?我想只有当ApiFirstEntityActions.searchRequest() 成功并且ApiFirstEntityActions.searchSuccess() 已经完成时,我才正确创建ApiSecondEntityActions.searchRequest() 的第三种选择?
谢谢!
【问题讨论】: