У меня есть угловой код, и история такова.У меня 3 HTTP-вызова, и из одного вызова мне нужен специальный заголовок (X), который требуется для двух других HTTP-вызовов, и я не могу контролировать выполнение этих вызовов.Поэтому, когда HTTP-вызов, требующий заголовка X, идет перед HTTP-вызовом, который дает мне заголовок X, как я могу удержать вызов и позволить определенному HTTP-вызову пойти и получить заголовок X и продолжить остальные вызовы с помощьюЗаголовок X добавлен к остальным HTTP-вызовам?Может показаться, что я пытаюсь создать очередь HTTP-вызовов, пока не получу заголовок X и не продолжу остальные вызовы снова.Некоторая помощь будет оценена.Код выглядит следующим образом.
шаблон:
<button class="btn btn-primary" (click)="do()"> Do </button>
Файл App.ts
export class AppComponent {
constructor(private dataService: DataService) {}
public do(): void {
this.dataService.first().subscribe();
this.dataService.second().subscribe((res) => {
this.dataService.third().subscribe();
});
}
}
data-service.ts, который имеет 3 HTTP-вызова
const httpOptions1 = {
headers: new HttpHeaders({ 'A': 'A' })
};
const httpOptions2 = {
headers: new HttpHeaders({ 'X': 'X' })
};
const httpOptions3 = {
headers: new HttpHeaders({ 'B': 'B' })
};
@Injectable()
export class DataService {
private apiUrl = 'https://jsonplaceholder.typicode.com/posts';
constructor(private http: HttpClient) {}
public first(): Observable<any> {
console.log('Call One')
return this.http.get(`${this.apiUrl}`, httpOptions1);
}
public second(): Observable<any> {
console.log('Call Two')
return this.http.get(`${this.apiUrl}`, httpOptions2);
}
public third(): Observable<any> {
console.log('Call Three')
return this.http.get(`${this.apiUrl}`, httpOptions3);
}
}
Это второй вызов с моим заголовком X, и от Interceptor я хочу сделать следующее: когда вызов first()
сработает, я хочу удержать его, добавить и разрешить вызов second()
и получите заголовок X, а затем повторно выполните вызов first()
с уровня перехватчика.
Ниже приведен код перехватчика
private pocessed: boolean = false;
private queue: any[] = [];
constructor() {}
public intercept(req: HttpRequest<any>, delegate: HttpHandler): Observable<any> {
/**
* Filter a certain http call with a certain X http header where this call provides a new header
* to be appended to all other http calls
*/
if (req.headers.has('X')) {
return delegate.handle(req).do((event) => {
if (event.type === HttpEventType.Response) {
// new header data acquired; hence the boolean turned to true
this.pocessed = true;
}
});
} else if (this.pocessed) {
/**
* if new header data acquired, append the new header to the rest of the calls
*/
if (this.queue.length > 0) {
// append header data to previous http calls
this.queue.forEach(element => {
let request = new HttpRequest(element.req['method'], element.req['url'], element.req['body'], {
headers: element.req['headers'],
reportProgress: true,
params: element.req['params'],
responseType: element.req['responseType'],
withCredentials: element.req['withCredentials']
});
// this.fakeIntercept(request, element.next);
});
}
// if new header data acquired, append the header to the rest of the calls
req = req.clone({ setHeaders: { 'X': 'X' } });
return delegate.handle(req).do((event) => console.log(event));
} else {
/**
* these http calls need X header but the call to get the X header hasnt gone yet
* therefor storing these calls in a queue to be used later when the header arrives
*/
this.queue.push({req: req, next: delegate});
return Observable.empty<any>();
}
}
fakeIntercept(req: HttpRequest<any>, delegate: HttpHandler): Observable<any> {
req = req.clone({ setHeaders: { 'X': 'X' } });
return delegate.handle(req);
}
Если вам, ребята, нужны какие-либо разъяснения, пожалуйста, нажмитеменя в комментариях.Если вы видите что-то, что я сделал неправильно, пожалуйста, поделитесь со мной.Любые улучшения в коде приветствуются.