我必须进行多个API调用(http请求)才能获取所需的所有数据。
由于我必须进行2个独立的API调用,两个调用均应以检索数据完成,因此我尝试与之同步。
我在打字稿/角度方面有将近0的经验,并且无法通过Google找到解决方案。
以下是我正在进行的API调用(签名):
public supportedLanguages(observe?: 'body', reportProgress?: boolean): Observable<Array<string>>;
public getAllFilters(acceptLanguage?: string, observe?: 'body', reportProgress?: boolean): Observable<Array<Filter>>;
这是我当前用来填写Array<Type>
的代码:
this.langService.supportedLanguages().subscribe(langs => setTimeout(() =>
this.langs.push(...langs), 1000));
this.categorieService.getAllFilters('de').subscribe(categories => setTimeout(() => {
this.categories.push(...categories), 1000));
我猜测这不是检索数据的正确方法,但是我还没有找到更好的方法(我对Typescript / angular非常陌生)。
等待加载所述数据的正确步骤是什么?
答案 0 :(得分:3)
您可以使用
(我正在使用“ rxjs”:“ ^ 5.5.11”)。
forkJoin
import 'rxjs/add/observable/forkJoin';
import { Observable } from 'rxjs';
import { Subscription } from 'rxjs/Subscription';
/* Multiple Service calls are asynchronism. use forkJoin to group service calls */
Observable.forkJoin(
this.supportedLanguages();
this.getAllFilters()
).subscribe(
response =>{
//response[0] is data returned by API supportedLanguages
//response[1] is data returned by API getAllFilters
}
error => console.log("Error: ", error),
() =>{
//All the API calls are completed here. Put your code here
//codes should be executed after the completion of all API calls
}
)
答案 1 :(得分:1)
您可以尝试从rxjs进行forkJoin:
forkJoin(
this.langService.supportedLanguages(),
this.categorieService.getAllFilters('de'))
)
.subscribe([langs, categories]=>{
...
})
答案 2 :(得分:1)
您也可以只使用async,await和promises的组合。
首先,您必须将.toPromise()
附加到服务方法中。然后在component.ts文件中添加以下方法...
private async fetchData() {
return await Promise.all([
this.langService.supportedLanguages();
this.categoryService.getAllFilters();
]).then(res => {
this.langs.push(res[0]); //res[0] is data returned by API supportedLanguages
this.categories.push(res[1]); //res[1] is data returned by API getAllFilters
this.status = true; // Confirms that now you have all your data back
}
}
在this.fetchData()
内致电ngOnInit()
然后,您可能会有一个状态变量,该变量已初始化为false
,然后在返回所有数据后将其设置为true
。
答案 3 :(得分:0)
您可以在Rxjs 6中使用 ForkJoin :
import {forkJoin} from 'rxjs';
// ...
forkJoin(
this.langService.supportedLanguages(),
this.categorieService.getAllFilters('de'))
).subscribe([langs, categories] => {
// ...
})
或者,您可以将2个API调用放在 Promise 中:
function recoverData() {
return new Promise((resolve, reject) => {
this.langService.supportedLanguages().subscribe(langs => this.langs.push(...langs), 1000);
this.categorieService.getAllFilters('de').subscribe(categories => this.categories.push(...categories), 1000);
resolve();
});
}
然后像这样使用它:
recoverData().then(() => {
// Some code
});
答案 4 :(得分:0)
如果您希望同时调用API并同时返回,则可以使用 rxjs 中的 ForkJoin ,有关documentation
forkJoin(
this.langService.supportedLanguages(),
this.categorieService.getAllFilters('de'))
).subscribe(x =>
console.log(x[0]); //result from api call 1
console.log(x[1]); //result from api call 2
)
但是如果要调用第一个api,则在第一个api完成后,您要调用第二个api。您可以使用 concatMap ,查看有关documentation here的信息,可能在第二个api需要第一个
参数时使用的concat映射this.langService.supportedLanguages().pipe(
concatMap(resultFromApi1 => this.categorieService.getAllFilters('de'))
).subscribe(x => console.log(x)) //x = result from api 2;
我在打字稿/角度方面有将近0的经验,找不到 通过Google解决方案。
您必须尝试不同的方式,不仅导致角度变角。如“ rxjs”等。您需要知道使用的是什么库js。并仔细对待版本,确实会造成一些棱角分明-关于版本,确实令人困惑,并且由于结构写法有些不同而有所不同