问题
I've been looking for a solution all over the web, but couldn't find anything that fits my user case. I'm using the MEAN stack (Angular 6) and I have a registration form. I'm looking for a way to execute multiple HTTP calls to the API and each one is dependent on the returned result from the previous one. I need something that looks like this:
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 */ }
);
What combination of RxJS operators do I need to use to achieve this? One possible solution would be to nest multiple subscriptions, but I want to avoid that and do it better with RxJS. Also need to think about error handling.
回答1:
For calls that depend on previous result you should use 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 */ }
);
if your async method does not depend on return value of the precedent async call you can use
concat(method(),method2(),method3()).subscribe(console.log)
回答2:
Try this , Angular provides feature to call multiple API at a time.
forkJoin()
You will get data in array
as in same sequence which you call API.
Ex:
forkJoin(request1, request2)
.subscribe(([response1, response2]) => {
You can find more read
I have also given another answer. Please check this, it may also helps you.
回答3:
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];
});
}
}
回答4:
Let me show you how to here, assuming I have much of emails I want to deliver an email to sequentially:
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(() => { });
}
I hope this helps.
来源:https://stackoverflow.com/questions/53560652/how-to-make-a-sequence-of-http-requests-in-angular-6-using-rxjs