Embora não seja a minha especialidade, estou dando manutenção em uma aplicação web desenvolvida com Angular (e, portanto, com código em TypeScript). Por estes dias apareceu um bug que acho curioso o suficiente para fazer este post.
Reduzindo o código ao mínimo, temos uma rotina chamada quando um botão na tela é pressionado. Esta rotina precisa chamar duas APIs externas e exibir a mensagem "Aguarde" enquanto aguarda as respostas. No código abaixo, a variável "aguarde" controla a exibição da mensagem (pela magia do Angular).
O código acima funcionava (aparentemente) até que uma mudança de implementação tornou a API 2 muito demorada. Foi aí que se percebeu que o "Aguarde" era retirado antes da hora.
Para entender o que acontece, é preciso saber que o código acima não roda sequencialmente, de cima para baixo. Os métodos chamaApi1 e chamaApi2 retornam "promises", que é a forma moderna de programar JavaScript de forma assíncrona. Ao executar a chamaApi1 e chamaApi2, a execução é suspensa até a chamada ser concluída (quando a "promise" é resolvida); neste ponto são executadas as rotinas associadas a then, catch e finally. Usando cores para indicar o que é executado quando:
A parte destacada em amarelo é executada primeiro. Quando a primeira "promise" é resolvida, serão executados os trechos em azul. O trecho em verde é executado quando a segunda chamada a API é concluída.
O resultado é que o finally() é executado quando a chamada à primeira API é concluída, enquanto a segunda chamada ainda está em execução.
Se você quiser ver isso no seu navegador, pressione F12 (ou a combinação de teclas que abre as Ferramentas do Desenvolvedor), selecione Console, copie o texto abaixo e pressione Enter para executar.
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const teste = () => {
console.log('Inicio');
delay(1000)
.then (() => {
console.log('Terminou delay 1');
delay(2000)
.then(() => {
console.log('Terminou delay 2');
})
.finally(() => {
console.log('Finally 2');
})
})
.finally(() => {
console.log('Finally 1');
});
}
teste()



Nenhum comentário:
Postar um comentário