Вы можете использовать оператор delayWhen
, который будет задерживать излучаемые значения на основе другой наблюдаемой.
для этого вы можете создать наблюдаемое как:
function renewTokenIfNeeded$(): Observable<void> {
console.log('Renew token start');
/**
* Here you should have have :
* If current token is valid,
* ---- then return of(number),
* else
* ---- then return this.http.post([...])
*/
// for demonstration prupose i always renew the token.
return of(null).pipe(delay(
Math.floor(Math.random() * 1000) + 1
), tap(() => console.log('renew token stop')));
}
/**
* Each 100 ms i trigger new dummy http request. By exhaustMap i will ignore all future "interval" emission until my dummy http request is complete stream.
*/
const renewTokensTimer$ = interval(100).pipe(exhaustMap(() => renewTokenIfNeeded$()));
поток данных будет выглядеть так:
|...|...|...|................|...|...|...|
1 / Вот так у меня есть поток, который будет выдавать новое число каждые 100 мс, пока вы не посчитаете свой ток грязным.
2 / Затем он выполнит http-запрос для получения нового.
3 / Наблюдаемый источник интервала не будет выдавать новое значение, пока вы не исчерпаете запрос http.
тогда вы можете просто использовать его следующим образом:
of(null) // Create dummy observable.
.pipe(delayWhen(() => renewTokenIfNeeded$())) // Delay it if token have to be renew.
.pipe(mergeMap(() => myRegularHttpRequest$)) // perform my http request, i am 100% here i have fresh JWT
.subscribe(console.log) // You can safely consume the API answer.
live-документ