问题
In my app, to call all the POST
request I have used a service
.
When I get a specific code (E.x : 401) from the server, I call an API to fetch new token.
Till the another token is received, if there's any other API call from, I store all those requests in an array. It may be n requests. For now assume there are 3 API call while the call for newToken API is in progress.
Once I get a new token I have to pass that in all the subsequent API's. Now I have to execute all the pending API requests and give data to their respective calls.
Code Example :
api.service.ts
POST(URL , param){
return new Observable<any>(observer => {
let headers = new HttpHeaders({
'Content-Type': 'Content-Type': 'application/json'
});
let options = {
headers: headers
};
this.http.post(URL, param, options)
.subscribe(data => {
var apiRes: any = data;
this.inValidSession();
observer.next();
observer.complete();
}
......
// For execute pending request I have set this
for (let i = 0; i < this.queue.length; i++) {
this.REPOST(this.queue[i].param, this.queue[i].url).subscribe((queueResponse) => {
observer.next(queueResponse);
observer.complete();
this.queue.shift();
});
}
}
user.component.ts
ngOnInit(){
this.getUserData();
this.getProductData();
}
getUserData(){
this.apiService.post({},'/apiName').subscribe((response) => {
console.log(response);
})
}
getProductData(){
this.apiService.post({},'/apiName2').subscribe((response) => {
console.log(response);
})
}
Issue is , when I execute all pending API's, I get data in the console. But not subscribe
from service file to respective .ts
file's function.
Note: I get subscribed data in only one function not each. In other words, I get both API res in getProductData()
function. I don't know why.
Please help me if any one has solution.
回答1:
You can use
forkJoin()
To handle multiple calls at the same time, where you can call multiple request
and after subscribing you will get an array
of resoponse.
eg
forkJoin(Service1.call1,
Service2.call2)
.subscribe(([call1Response, call2Response]) => {
Where service1 and service2 are service which have function ccall1 and call2 , that are having return
type Observable
You can find more Here
回答2:
Using ForkJoin
We are going to use an operator called forkJoin. If you are familiar with Promises, this is very similar to Promise.all().
The forkJoin() operator allows us to take a list of Observables and
execute them in parallel.Once every Observable in the list emits a value, the forkJoin will
emit a single Observable value containing a list of all the resolved values from the Observables in the list.In this example, I want to load a character and a characters homeworld. We already know what the ids are for these resources so we can request them in parallel.
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 character = this.http.get('https://swapi.co/api/people/1'); let characterHomeworld = this.http.get('http://swapi.co/api/planets/1'); forkJoin([character, characterHomeworld]).subscribe(results => { // results[0] is our character // results[1] is our character homeworld results[0].homeworld = results[1]; this.loadedCharacter = results[0]; }); } }
In above example, we capture the character and characterHomeworld Observable in variables. Observables are lazy, so they won’t execute until someone subscribes. When we pass them into forkJoin the forkJoin operator will subscribe and run each Observable, gathering up each value emitted and finally emitting a single array value containing all the completed HTTP requests. This is a typical pattern with JavaScript UI programming. With RxJS this is relatively easy compared to using traditional callbacks.
With the mergeMap / flatMap and forkJoin operators we can do pretty sophisticated asynchronous code with only a few lines of code.
回答3:
Easy Method
use forkjoin()
public sample(): Observable<any[]>
{
let call1=this.http.get(this._url+'/v1/sample1')
let call2=this.http.get(this._url+'/v1/sample2')
let call3=this.http.get(this._url+'/v1/sample3')
return forkJoin([call1, call2,call3]);
}
回答4:
Use zip
lib from rxjs
import { zip } from "rxjs";
myFun() {
zip(service.api1, service.api2)
.subscribe(([response1, response2]) => {
console.log(response1);
console.log(response2);
})
}
来源:https://stackoverflow.com/questions/53002461/how-to-call-multiple-api-and-subscribe-in-angular-6