如何使用 RxJS 在 Angular 6 中发出一系列 http 请求
How to make a sequence of http requests in Angular 6 using RxJS
我一直在网上寻找解决方案,但找不到适合我的用户案例的解决方案。我正在使用 MEAN 堆栈 (Angular 6),并且我有一张注册表。我正在寻找一种方法来对 API 执行多个 HTTP 调用,每个调用都依赖于前一个返回的结果。我需要这样的东西:
firstPOSTCallToAPI('url', data).pipe(
result1 => secondPOSTCallToAPI('url', result1)
result2 => thirdPOSTCallToAPI('url', result2)
result3 => fourthPOSTCallToAPI('url', result3)
....
).subscribe(
success => { /* display success msg */ },
errorData => { /* display error msg */ }
);
我需要使用哪些 RxJS 运算符组合来实现此目的?一种可能的解决方案是嵌套多个订阅,但我想避免这种情况并使用 RxJS 做得更好。还需要考虑错误处理。
试试这个,Angular 提供一次调用多个 API 的功能。
forkJoin()
您将在 array
中获取数据,与您调用 API 的顺序相同。
例如:
forkJoin(request1, request2)
.subscribe(([response1, response2]) => {
您可以找到更多 read
我还给了另一个。请检查这个,它也可以帮助你。
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';
@Injectable()
export class DataService {
constructor(private http: HttpClient) { }
public requestDataFromMultipleSources(): Observable<any[]> {
let response1 = this.http.get(requestUrl1);
let response2 = this.http.get(requestUrl2);
let response3 = this.http.get(requestUrl3);
return Observable.forkJoin([response1, response2, response3]);
}
}
The above example shows making three http calls, but in a similar way you can request as many http calls as required
import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";
@Component({
selector: 'app-page',
templateUrl: './page.component.html',
styleUrls: ['./page.component.css']
})
export class DemoComponent implements OnInit {
public responseData1: any;
public responseData2: any;
public responseData3: any;
constructor(private dataService: DataService) {}
ngOnInit() {
this.dataService.requestDataFromMultipleSources().subscribe(responseList => {
this.responseData1 = responseList[0];
this.responseData2 = responseList[1];
this.responseData3 = responseList[1];
});
}
}
对于依赖于先前结果的调用,您应该使用 concatMap
firstPOSTCallToAPI('url', data).pipe(
concatMap(result1 => secondPOSTCallToAPI('url', result1))
concatMap( result2 => thirdPOSTCallToAPI('url', result2))
concatMap(result3 => fourthPOSTCallToAPI('url', result3))
....
).subscribe(
success => { /* display success msg */ },
errorData => { /* display error msg */ }
);
如果您的异步方法不依赖于 return 先前异步调用的值,您可以使用
concat(method(),method2(),method3()).subscribe(console.log)
让我在这里向您展示如何操作,假设我有很多电子邮件,我想按顺序向其发送电子邮件:
sendEmails() {
this.isLoading = true;
const calls = this.emails <<-- assume this contain an array of emails
.map(email => this.userEmailService.deliver({email: email, userId: 1242}));
from(calls) <<-- make use of the from.
.pipe(
concatMap(res => res),
finalize(() => this.isLoading = false)
).subscribe(() => { });
}
希望对您有所帮助。
我遇到了同样的问题,这是我的解决方案,使用 pipe
和 concatMap
作为数组来获取开始时间和结束时间之间的时间段的序列数据。
这是数组请求时的通用解决方案。
我为谁分忧
let currentReplayData = [];
let timerange = [[t1, t2], [t3, t4]]; // array of start and end time
from(timerange).pipe(
concatMap(time => <Observable<any>>this.dataService.getData(time[0],time[1]))
).subscribe(val => {
//console.log(val)
this.currentReplayData = this.currentReplayData.concat(val);
});
MergeMap
正是您要找的东西
firstPOSTCallToAPI('url', data).pipe(
mergeMap(result1 => secondPOSTCallToAPI('url', result1)),
mergeMap(result2 => thirdPOSTCallToAPI('url', result2)),
mergeMap(result3 => fourthPOSTCallToAPI('url', result3)),
// ...
).subscribe(
success => {
// here you will get response of LAST request (fourthPOSTCallToAPI)
},
errorData => { /* display error msg */ }
);
// I assume that
// secondPOSTCallToAPI, thirdPOSTCallToAPI and fourthPOSTCallToAPI
// returns obserwable eg. return this.http.get<Book>(apiUrl);
我一直在网上寻找解决方案,但找不到适合我的用户案例的解决方案。我正在使用 MEAN 堆栈 (Angular 6),并且我有一张注册表。我正在寻找一种方法来对 API 执行多个 HTTP 调用,每个调用都依赖于前一个返回的结果。我需要这样的东西:
firstPOSTCallToAPI('url', data).pipe(
result1 => secondPOSTCallToAPI('url', result1)
result2 => thirdPOSTCallToAPI('url', result2)
result3 => fourthPOSTCallToAPI('url', result3)
....
).subscribe(
success => { /* display success msg */ },
errorData => { /* display error msg */ }
);
我需要使用哪些 RxJS 运算符组合来实现此目的?一种可能的解决方案是嵌套多个订阅,但我想避免这种情况并使用 RxJS 做得更好。还需要考虑错误处理。
试试这个,Angular 提供一次调用多个 API 的功能。
forkJoin()
您将在 array
中获取数据,与您调用 API 的顺序相同。
例如:
forkJoin(request1, request2)
.subscribe(([response1, response2]) => {
您可以找到更多 read
我还给了另一个
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';
@Injectable()
export class DataService {
constructor(private http: HttpClient) { }
public requestDataFromMultipleSources(): Observable<any[]> {
let response1 = this.http.get(requestUrl1);
let response2 = this.http.get(requestUrl2);
let response3 = this.http.get(requestUrl3);
return Observable.forkJoin([response1, response2, response3]);
}
}
The above example shows making three http calls, but in a similar way you can request as many http calls as required
import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";
@Component({
selector: 'app-page',
templateUrl: './page.component.html',
styleUrls: ['./page.component.css']
})
export class DemoComponent implements OnInit {
public responseData1: any;
public responseData2: any;
public responseData3: any;
constructor(private dataService: DataService) {}
ngOnInit() {
this.dataService.requestDataFromMultipleSources().subscribe(responseList => {
this.responseData1 = responseList[0];
this.responseData2 = responseList[1];
this.responseData3 = responseList[1];
});
}
}
对于依赖于先前结果的调用,您应该使用 concatMap
firstPOSTCallToAPI('url', data).pipe(
concatMap(result1 => secondPOSTCallToAPI('url', result1))
concatMap( result2 => thirdPOSTCallToAPI('url', result2))
concatMap(result3 => fourthPOSTCallToAPI('url', result3))
....
).subscribe(
success => { /* display success msg */ },
errorData => { /* display error msg */ }
);
如果您的异步方法不依赖于 return 先前异步调用的值,您可以使用
concat(method(),method2(),method3()).subscribe(console.log)
让我在这里向您展示如何操作,假设我有很多电子邮件,我想按顺序向其发送电子邮件:
sendEmails() {
this.isLoading = true;
const calls = this.emails <<-- assume this contain an array of emails
.map(email => this.userEmailService.deliver({email: email, userId: 1242}));
from(calls) <<-- make use of the from.
.pipe(
concatMap(res => res),
finalize(() => this.isLoading = false)
).subscribe(() => { });
}
希望对您有所帮助。
我遇到了同样的问题,这是我的解决方案,使用 pipe
和 concatMap
作为数组来获取开始时间和结束时间之间的时间段的序列数据。
这是数组请求时的通用解决方案。
我为谁分忧
let currentReplayData = [];
let timerange = [[t1, t2], [t3, t4]]; // array of start and end time
from(timerange).pipe(
concatMap(time => <Observable<any>>this.dataService.getData(time[0],time[1]))
).subscribe(val => {
//console.log(val)
this.currentReplayData = this.currentReplayData.concat(val);
});
MergeMap
正是您要找的东西
firstPOSTCallToAPI('url', data).pipe(
mergeMap(result1 => secondPOSTCallToAPI('url', result1)),
mergeMap(result2 => thirdPOSTCallToAPI('url', result2)),
mergeMap(result3 => fourthPOSTCallToAPI('url', result3)),
// ...
).subscribe(
success => {
// here you will get response of LAST request (fourthPOSTCallToAPI)
},
errorData => { /* display error msg */ }
);
// I assume that
// secondPOSTCallToAPI, thirdPOSTCallToAPI and fourthPOSTCallToAPI
// returns obserwable eg. return this.http.get<Book>(apiUrl);