如何处理Angular 7中的嵌套HTTP请求?
我有一个从服务器获取数据的通用服务。当收到响应时,我正在使用映射器函数将纯JSON数据映射到所需的模型。对于mapper函数中的某些类类型,我需要从服务器获取一些额外的数据。如何强制映射器函数等待第二个请求 这是我的get函数:如何处理Angular 7中的嵌套HTTP请求?,angular,httprequest,angular7,fork-join,Angular,Httprequest,Angular7,Fork Join,我有一个从服务器获取数据的通用服务。当收到响应时,我正在使用映射器函数将纯JSON数据映射到所需的模型。对于mapper函数中的某些类类型,我需要从服务器获取一些额外的数据。如何强制映射器函数等待第二个请求 这是我的get函数: getChildren(params: ITreeQueryParams): Observable<Optional<T[]>> { params.id = isPresent(params.id) ? params.id : 0;
getChildren(params: ITreeQueryParams): Observable<Optional<T[]>> {
params.id = isPresent(params.id) ? params.id : 0;
params.parentId = isPresent(params.parentId) ? params.parentId : 0;
params.isRoot = isPresent(params.isRoot) ? params.isRoot : false;
params.additionalId = isPresent(params.additionalId) ?
params.additionalId : 0;
return this.http.get<IListResponse<T>>
(`${this.resourceUrl}/getChildren/${params.id}/${params.parentId}/${params.isRoot}/${params.additionalId}`,
{
observe: 'response'
}).pipe(map((resp) => this.mapResponse(resp,this.model)));
}
protected mapResponse(resp: any, model: IAsset): void {
if (resp) {
this.anotherTreeService.getNodeDetail(resp.id, resp.isRoot).subscribe(res => {
model.additionalData = {canEdit: res.length > 0 ? true : false};
});
if (resp.name) {
model.title = resp.name;
}
}
}
如果我理解正确的话,你只需要提出一个请求,然后再提出子请求 为此,如果需要接受多个子请求,可以使用
switchMap
和forkJoin
下面是如何重写代码(我将编写一个简化版本)
switchMap
所做的是在每次源发射(您的第一个观测值)之后,它在回调中订阅返回的观测值(如果它已经订阅了,它将首先从回调观测值取消订阅)
forkJoin
的工作原理类似于Promise.all
。您可以在那里传递一个数组、对象或多个观察值(现在已弃用),然后在subscribe中获得一个数组或对象
请注意,forkJoin
仅在所有可观察对象完成时才会发出每个可观察对象的最后一个值。另外,如果任何可观察对象完成而不发出值forkJoin
也完成而不发出值。因为所有的http.whatever
都可以通过一个next
和立即complete
来观察,之后你就不用担心了
此外,如果有任何可观察到的错误
forkJoin
错误。如果我理解正确,您只需提出一个请求并提出子请求即可
为此,如果需要接受多个子请求,可以使用switchMap
和forkJoin
下面是如何重写代码(我将编写一个简化版本)
switchMap
所做的是在每次源发射(您的第一个观测值)之后,它在回调中订阅返回的观测值(如果它已经订阅了,它将首先从回调观测值取消订阅)
forkJoin
的工作原理类似于Promise.all
。您可以在那里传递一个数组、对象或多个观察值(现在已弃用),然后在subscribe中获得一个数组或对象
请注意,forkJoin
仅在所有可观察对象完成时才会发出每个可观察对象的最后一个值。另外,如果任何可观察对象完成而不发出值forkJoin
也完成而不发出值。因为所有的http.whatever
都可以通过一个next
和立即complete
来观察,之后你就不用担心了
此外,如果出现任何可观察到的错误,请参见forkJoin错误。RxJS中有大量运算符可以实现您想要的功能。当数据模型本身不包含所有数据,并且需要单独调用以根据第一个结果检索其他数据时,您经常会看到这样一个示例:
this.myFirstService.getById(id).pipe(
map(data => jsonToMyModel(data)),
tap(model => this.data = model),
switchMap(model => {
return this.mySecondService.getListById(model.id)
}),
tap(secondData => this.data.list = secondData)
).subscribe()
这改变了您正试图实现的目标,因为可以通过使用forkJoin()
或mergeMap()
将所有数据最终放在可观察对象返回的一个模型中。这些运算符中的任何一个都可以在此类情况下使用
希望这有帮助。要想更清楚、更直接地说明你想要什么,需要一个更完整的问题,其中包括一些你想要什么和你尝试过什么的例子。RxJS中有很多操作符可以实现你想要的。当数据模型本身不包含所有数据,并且需要单独调用以根据第一个结果检索其他数据时,您经常会看到这样一个示例:
this.myFirstService.getById(id).pipe(
map(data => jsonToMyModel(data)),
tap(model => this.data = model),
switchMap(model => {
return this.mySecondService.getListById(model.id)
}),
tap(secondData => this.data.list = secondData)
).subscribe()
这改变了您正试图实现的目标,因为可以通过使用forkJoin()
或mergeMap()
将所有数据最终放在可观察对象返回的一个模型中。这些运算符中的任何一个都可以在此类情况下使用
希望这有帮助。要想更清楚、更直接地说明你想要什么,就需要一个更完整的问题,包括你想要什么和你尝试过什么。在RXJS中使用Observable.CombineTest或Observable.forkJoin更好使用Observable.CombineTest或Observable.forkJoin在RXJS中更好