SwiftUI Series 10 | Carregamento assíncrono SwiftUI: ligação de tarefa, assíncrono/aguarde e status da interface
O que é realmente difícil é manter o carregamento, os resultados, os erros e o ciclo de vida da página consistentes
Depois que muitas páginas SwiftUI são carregadas de forma assíncrona, os problemas começam a aumentar:
onAppearrepetirá a solicitação- O estado de carregamento é instável
- Resultados antigos mudarão a página atual de volta
- A tarefa ainda está sendo escrita de volta depois de sair da página
Esses problemas podem parecer problemas Task ou async/await superficialmente, mas os motivos mais fundamentais são frequentemente:
O ciclo de vida da tarefa assíncrona e o ciclo de vida do estado da página não estão alinhados.
Então, o que realmente temos que lidar é:
- Quando começa a solicitação?
- Serei elegível para mudar a página depois que os resultados voltarem?
- Quando as tarefas antigas devem expirar?
- Como esses estados de carregamento/erro/conteúdo são mutuamente exclusivos?
1. A armadilha mais fácil é considerar a página assíncrona como “uma solicitação + um valor booleano”
Muitas páginas serão inicialmente escritas assim:
-Um isLoading
-Um items
-Um errorMessage
Adicione outro:
Task {
await load()
}
Claro que no começo vai funcionar, mas assim que a página começar a suportar:
- tente novamente
- Puxe para baixo para atualizar
- Pesquisa
- Comutação condicional
Os problemas surgirão um após o outro. Porque a página real é um conjunto de tarefas que podem se substituir e se cobrir.
2. O verdadeiro núcleo das páginas assíncronas está no fluxo de estado
Se você entender o carregamento assíncrono apenas como “recuperação de dados”, será fácil ignorar que o que realmente interessa à página são estes estados:
- Carregando ao entrar pela primeira vez
- Atualizar com base no conteúdo existente
- Tente novamente após falha no carregamento
- Solicitação após alteração de certas condições
Ambas são “cargas”, mas não são a mesma coisa na semântica da página.
Se tudo for representado por apenas um isLoading, a página logo ficará confusa.
Então uma ideia mais prática geralmente é:
- Primeiro defina em que estado semântico a página se encontra atualmente
- Deixe a tarefa assíncrona conduzir essa mudança de fluxo de estado
3. onAppear + Task geralmente se torna mais perigoso quanto mais você o escreve.
Porque é tão fácil.
Uma situação comum é escrever naturalmente:
.onAppear {
Task {
await viewModel.load()
}
}
Este código em si não está necessariamente errado, mas o perigo é que é muito fácil padronizá-lo:
- A página aparece uma vez
- Solicitação para enviar uma vez
- Altere o status uma vez após retornar
Em projetos reais, estas três suposições podem não ser verdadeiras.
Portanto, a chave para saber se o carregamento assíncrono é realmente estável não é se existe Task, mas sim:
- Se tarefas semelhantes são gerenciadas de maneira uniforme -Se tarefas antigas serão canceladas ou expiradas
- Se o resultado precisa ser verificado em relação ao contexto atual
4. Um mal-entendido comum: se o resultado for bem-sucedido, você chegará diretamente à página.
Muitas páginas estão em estado desordenado e a causa raiz está aqui.
Por exemplo:
- Palavras-chave mudaram
- Pedidos antigos voltam mais tarde
- Resultados antigos ainda alteram a página
Do ponto de vista da solicitação, ele não falhou, mas do ponto de vista da página, expirou.
Portanto, uma coisa muito importante nas páginas assíncronas é:
Nem todos os resultados retornados com sucesso são automaticamente elegíveis para write-back da UI atual.
Portanto, o carregamento assíncrono de páginas geralmente não pode apenas verificar “se o resultado foi obtido”, mas também “se o resultado ainda é válido agora”.
5. Uma direção mais estável: feche a tarefa de carregamento em vez de permitir que cada evento da UI envie sua própria solicitação
Se uma página suportar:
- carga inicial
- tente novamente
- atualizar
- Filtrar alterações
A abordagem mais estável geralmente é agrupar tarefas semelhantes.
Por exemplo:
- Todas as entradas chamam o mesmo
reload() - A tarefa atualmente ativa é mantida pelo ViewModel
- Quando novas tarefas aparecem, as tarefas antigas são canceladas ou consideradas inválidas.
Dessa forma, o estado da página será pelo menos mais fácil de manter consistente porque:
- Está claro quem está carregando
- Também está claro quem pode encerrar o carregamento
6. Conclusão: O que o carregamento assíncrono do SwiftUI realmente precisa resolver é se a tarefa e o status da página podem ser explicados claramente.
Para resumir, eu diria:
Ao lidar com carregamento assíncrono no SwiftUI, a verdadeira dificuldade é manter consistentes o ciclo de vida da tarefa, a validade dos resultados e o fluxo do estado da página.
Enquanto essas três coisas não forem estabelecidas, a página continuará a crescer:
- Repetir solicitação
- Escreva resultados antigos
- confusão de carregamento
Geralmente, esses problemas não podem ser resolvidos escrevendo mais alguns Task.
What to read next
Want more posts about SwiftUI?
Posts in the same category are usually the best next step for reading more on this topic.
View same categoryWant to keep following #iOS?
Tags are useful for related tools, specific problems, and similar troubleshooting notes.
View same tagWant to explore another direction?
If you are not sure what to read next, return to the homepage and start from categories, topics, or latest updates.
Back home