[英]Multiple API calls with same request
我想使用传递不同 id 的相同端点进行多个 HTTP 调用。 有没有更好的方法从 UI 处理这个问题。 我们现在无法更改后端,有更好的方法吗?
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, forkJoin } from 'rxjs';
@Component({
selector: 'app-root',
templateUrl: 'app/app.component.html'
})
export class AppComponent {
loadedCharacter: {};
constructor(private http: HttpClient) {}
ngOnInit() {
let character1 = this.http.get('https://swapi.co/api/people/1');
let character2 = this.http.get('http://swapi.co/api/people/2');
forkJoin([character, character2]).subscribe(results => {
// results[0] is our character
// results[1] is our character2
});
}
}
您可以提取逻辑以在常见的 function 中创建可观察对象,并像下面这样使用它:
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, forkJoin } from 'rxjs';
@Component({
selector: 'app-root',
templateUrl: 'app/app.component.html'
})
export class AppComponent {
loadedCharacter: {};
constructor(private http: HttpClient) {}
ngOnInit() {
let character1 = this.createHttpObservable('1');
let character2 = this.createHttpObservable('2');
forkJoin([character, character2]).subscribe(results => {
// results[0] is our character
// results[1] is our character2
});
}
createHttpObservable(id:string) {
const url = 'https://swapi.co/api/people/';
return this.http.get(`url${id}`);
}
}
基本上有2个选项:
是您使用forkJoin()
将所有可观察对象组合成一个数组的选项吗
subscribe()
中加载所有数据forkJoin
发出值之前完成
您可以使用mergeMap()
作为您的 ID,并在其中一个可观察对象完成时做出反应
.subscribe()
中处理你发出的值有点不同归根结底,您需要决定哪种方法最适合您。 您的实施没有任何问题。 我注意到您将loadedCharacter
保留为object,所以老实说选项2 可能适合您的用例
选项 2的示例代码。 请参阅此stackblitz以获取小型演示:
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, from, Subject } from 'rxjs';
import { mergeMap, takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: 'app/app.component.html'
})
export class AppComponent {
private endSubs$ = new Subject();
loadedCharacter: {};
constructor(private http: HttpClient) {}
ngOnInit() {
/* ids of all the characters you want to load*/
const characterIds = [1, 2];
/* this will emit each id as a value */
from(characterIds).pipe(
/* merge each id to an Observable of the http get request */
mergeMap(id => this.http.get(`https://swapi.co/api/people/${id}`)),
/* cancel any pending requests when the component unloads.
this will avoid any RxJS memory leaks */
takeUntil(this.endSubs$)
).subscribe(
character => {
/* note that you will only receive 1 character at a time */
console.log('received character', character);
this.loadedCharacter[character.id] = character; // or whatever you want to do
},
err => console.log('Error loading a character', err),
() => console.log('All character requests have finished')
);
}
/* clean up our subscriptions when the component destroys */
ngOnDestory() {
this.endSubs$.next();
this.endSubs$.complete();
}
}
编辑:我添加了一些 RxJS 清理代码以避免任何 memory 从mergeMap
泄漏。 当此组件卸载时,任何挂起的请求都将被取消。 这是一个解释 Observable 清理的示例 SO 答案,这里是有关放置takeUntil()
的位置的相关 RxJS 文章。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.