javascript - 在上一个 GET 请求的对象可用后直接发送 GET 请求?
问题描述
初始化 MatchComponent 时,我想做 1. 获取获取 Match 对象的请求(Match 对象有一个成员 playerIDs) 2. 获取获取 Players 的请求(基于 Match 对象中的 playerIDs)
由于异步通信,我下面的代码不起作用。我该如何处理?
匹配组件.ts
@Component({
selector: 'app-match',
templateUrl: './match.component.html',
styleUrls: ['./match.component.css']
})
export class MatchComponent implements OnInit {
match: Match;
players: Player[];
constructor(private matchService: MatchService,
private playerService: PlayerService,
private route: ActivatedRoute) { }
ngOnInit() {
this.loadData();
}
loadData(): void {
const matchID = +this.route.snapshot.paramMap.get('id');
this.getMatchByUniqueID(matchID); // first get request
this.match.playerIDs.forEach(id => {
this.getPlayerByUniqueID(id); // get requests that can only work when the match object is set correctly
});
}
// ---------------------------------------------------------
// HTTP ----------------------------------------------------
// ---------------------------------------------------------
getMatchByUniqueID(id: number): void {
this.matchService.getMatch(id)
.subscribe(match => {
if (match.status === 'SUCCESS') {
this.match = Object.setPrototypeOf(match.data, Match.prototype);
}
});
}
getPlayerByUniqueID(id: number): void {
this.playerService.getPlayer(id)
.subscribe(player => {
if (player.status === 'SUCCESS') {
this.players.push(Object.setPrototypeOf(player.data, Player.prototype));
}
});
}
updateMatch(match: Match): void {
console.log('update');
this.matchService.updateMatch(match)
.subscribe(() => this.match);
}
}
匹配.ts
export class Match {
//...
playerIDs: number[]; /// IDs of players playing this match
//...
}
匹配服务.ts
import { Match } from './match';
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpHandler } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';
import { HttpResponseType } from './http.response';
@Injectable({
providedIn: 'root'
})
export class MatchService {
private matchesURL = 'http://localhost:8080/matches';
httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
constructor(private http: HttpClient) { }
getMatch(id: number): Observable<HttpResponseType<Match>> {
const url = `${this.matchesURL}/${id}`;
return this.http.get<HttpResponseType<Match>>(url)
.pipe(
// tap(_ => this.log(`fetched hero id=${id}`)),
catchError(this.handleError<HttpResponseType<Match>>(`getUser id=${id}`))
);
}
/** PUT: update the match on the server */
updateMatch(match: Match): Observable<any> {
return this.http.put(this.matchesURL + '/' + match.uniqueID, match, this.httpOptions).pipe(
// tap(_ => this.log(`updated user id=${user.id}`)),
catchError(this.handleError<Match>('updateMatch'))
);
}
// ...
解决方案
如果我正确理解您的需求,您想使用请求 1 中的数据提出请求 2。
这可以通过 RxJsswitchMap
运算符轻松完成。
所有你需要的是
// First you pipe to the source observable which GETs the data you need
this.firstRequest$.pipe(
// you may apply a filter() pipe which will pass data forth if it returns true
// like filter(res => res.status === 'SUCCESS')
// Then you call method which receives some needed data for second request
// and returns observable of 2nd request
switchMap(res => this.secondRequest(res.id))
).subscribe(res => {
// process the result of 2nd request
});
这是一个小例子
https://stackblitz.com/edit/rxjs-47hmp1?devtoolsheight=60
import { of } from 'rxjs';
import { map, filter, switchMap } from 'rxjs/operators';
// Here we get a source observable
function getFirstObservable() {
return of({
data: {
id: 3
},
status: 'SUCCESS',
});
}
// This is a second source which requires some data to receive first
function getSecondObservable(id: number) {
return of('I was called with id ' + id);
}
getFirstObservable().pipe(
// filter allows emmited values to pass only when resolves to true
filter(response => response.status === 'SUCCESS'),
// Allows us to subsribe to the observabe returned by callback when
// source observable emits value
switchMap(response => getSecondObservable(response.data.id))
).subscribe(result => {
console.log(result);
// handle result
// here goes the result of a second observable when and only when second observable
// emmits value
}, err => {
// handle error logic
})
推荐阅读
- flutter - Get 从颤动返回不同的响应,但是当我从移动设备上的 chrome 调用它时,它可以工作
- mysql - 这就是我到目前为止所坚持的我如何做 invoice_due_date
- c# - 在 WPF 中过滤到 CollectionViewSource 的绑定
- python - 如何在 Python 3.10 中的匹配情况下获取带空格的字符串
- python-3.x - 使用 browser.fill() 并获取 TypeError: fill() 需要 2 个位置参数,但给出了 3 个
- python - 如何在 Python 代码的 Applescript 函数中使用全局变量
- javascript - 如果在 Rhandsontable 中编辑单元格,则突出显示该行并跟踪所有更改
- pytorch - 在pytorch中构造参数组
- amazon-web-services - boto3 lamda 触发器不适用于 SNS 主题
- azure - 显示来自特定日志的先前日志的 KQL 查询