Quero mostrar um carregador ao fazer solicitações no meu aplicativo. Mas às vezes meu servidor responde rápido demais e o carregador simplesmente pisca por uma fração de segundo, causando uma experiência desagradável.
No passado, o que sempre fiz foi usar combineLatest
um timer
para criar um atraso mínimo na solicitação.
const request = getRequestPromise();
await lastValueFrom(combineLatest([request, timer(1000)]).pipe(mapRx(([x]) => x)))
O que isso faz é que se o servidor responder em menos de um segundo, basta esperar 1 segundo antes de resolver. Se, no entanto, o servidor responder em 3 segundos, este código não adicionará um segundo extra.
Isso tem funcionado muito bem. Mas acabei de perceber que se a solicitação falhar (resultando em uma exceção) ela não respeita o atraso mínimo. Ele é resolvido imediatamente e causa um flash desagradável do carregador.
Como posso fazer com que isso funcione para solicitações com falha e bem-sucedidas?
Preciso ainda ser capaz de lidar com o sucesso/erro da própria solicitação:
await lastValueFrom(combineLatest([request, timer(1000)])
.pipe(mapRx(([x]) => x)))
.then(() => console.log('handle successful request'))
.catch(() => console.log('handle error'))
Você pode usar materialize e dematerialize para isso, para que não haja nenhum erro no primeiro stream, e somente depois que combineLatest for resolvido e você retornar o valor da solicitação, você o desmaterializa para que, se houver um erro, ele jogue como esperado:
Acho que você pode agrupar
request
(o que, presumo, é uma promessa) com umfrom
Observable e usar umcatchError()
operador, para que a notificação de erro não se propague mais.