SwiftUI Seri 10| Pemuatan asinkron SwiftUI: Tautan tugas, asinkron/menunggu, dan status antarmuka
Yang paling sulit adalah menjaga konsistensi pemuatan, hasil, kesalahan, dan siklus hidup halaman
Setelah banyak halaman SwiftUI dimuat secara asinkron, masalah mulai meningkat:
onAppearakan mengulangi permintaan tersebut- Status pemuatan tidak stabil
- Hasil lama akan mengubah halaman saat ini kembali
- Tugas masih ditulis kembali setelah meninggalkan halaman
Masalah ini mungkin tampak seperti masalah Task atau async/await di permukaan, namun alasan yang lebih mendasar sering kali adalah:
Siklus hidup tugas asinkron dan siklus hidup status halaman tidak selaras.
Jadi yang sebenarnya harus kita tangani adalah:
- Kapan permintaannya dimulai?
- Apakah saya berhak mengubah halaman setelah hasilnya keluar?
- Kapan tugas lama harus berakhir?
- Bagaimana status pemuatan/kesalahan/konten ini saling eksklusif?
1. Kesalahan yang paling mudah adalah menganggap halaman asinkron sebagai “satu permintaan + satu nilai Boolean”
Banyak halaman awalnya akan ditulis seperti ini:
isLoadingitemserrorMessage
Tambahkan satu lagi:
Task {
await load()
}
Tentu saja ini akan berfungsi pada awalnya, tetapi segera setelah halaman tersebut mulai mendukung:
- coba lagi
- Tarik ke bawah untuk menyegarkan
- Cari
- Peralihan bersyarat
Masalah akan muncul silih berganti. Karena halaman sebenarnya adalah sekumpulan tugas yang mungkin saling menggantikan dan menutupi satu sama lain.
2. Inti sebenarnya dari halaman asinkron terletak pada aliran status
Jika Anda hanya memahami pemuatan asinkron sebagai “mengambil data kembali”, akan mudah untuk mengabaikan bahwa yang benar-benar dipedulikan laman tersebut adalah status berikut:
- Memuat saat pertama kali masuk
- Refresh berdasarkan konten yang ada
- Coba lagi setelah gagal memuat
- Permintaan setelah kondisi tertentu berubah
Keduanya adalah “muatan”, tetapi keduanya bukanlah hal yang sama dalam semantik halaman.
Jika semuanya diwakili oleh satu isLoading saja, halaman akan segera menjadi berantakan.
Jadi ide yang lebih praktis biasanya adalah:
- Pertama-tama tentukan status semantik halaman saat ini
- Biarkan tugas asinkron mendorong perubahan aliran status ini
3. onAppear + Task sering kali menjadi semakin berbahaya semakin sering Anda menulisnya.
Karena itu sangat mudah.
Situasi yang umum adalah menulis secara alami:
.onAppear {
Task {
await viewModel.load()
}
}
Kode ini sendiri belum tentu salah, namun bahayanya adalah kode ini terlalu mudah untuk ditetapkan secara default:
- Halaman muncul satu kali
- Permintaan untuk mengirim sekali
- Ubah status satu kali setelah kembali
Dalam proyek nyata, ketiga asumsi ini mungkin tidak benar.
Oleh karena itu, kunci apakah pemuatan asinkron benar-benar stabil bukanlah apakah terdapat Task, melainkan:
- Apakah tugas serupa dikelola secara seragam -Apakah tugas lama akan dibatalkan atau kedaluwarsa
- Apakah hasilnya perlu diverifikasi terhadap konteks saat ini
4. Kesalahpahaman umum: jika hasilnya berhasil, Anda akan langsung diarahkan ke halaman tersebut.
Banyak halaman dalam status tidak teratur, dan akar masalahnya ada di sini.
Misalnya:
- Kata kunci telah berubah
- Permintaan lama kembali lagi nanti
- Hasil lama masih berganti halaman
Dari sudut pandang permintaan, itu tidak gagal, tetapi dari sudut pandang halaman, itu kedaluwarsa.
Jadi satu hal yang sangat penting dalam halaman asinkron adalah:
Tidak semua hasil yang berhasil dikembalikan secara otomatis memenuhi syarat untuk menulis kembali UI saat ini.
Oleh karena itu, pemuatan halaman yang tidak sinkron biasanya tidak hanya melihat “apakah hasilnya sudah diperoleh”, tetapi juga harus melihat “apakah hasilnya masih valid saat ini”.
5. Arah yang lebih stabil: tutup tugas pemuatan daripada membiarkan setiap peristiwa UI mengirimkan permintaannya sendiri
Jika halaman mendukung:
- beban awal
- coba lagi
- menyegarkan
- Filter perubahan
Pendekatan yang lebih stabil biasanya adalah dengan mengelompokkan tugas-tugas serupa.
Misalnya:
- Semua entri pada akhirnya memanggil
reload()yang sama - Tugas yang sedang aktif dipegang oleh ViewModel
- Ketika tugas baru muncul, tugas lama dibatalkan atau dinilai tidak valid.
Dengan cara ini status halaman setidaknya akan lebih mudah untuk tetap konsisten karena:
- Jelas siapa yang memuat
- Jelas juga siapa yang dapat mengakhiri pemuatan
6. Kesimpulan: Yang benar-benar perlu ditangani oleh pemuatan asinkron SwiftUI adalah apakah tugas dan status halaman dapat dijelaskan dengan jelas.
Singkatnya, saya akan mengatakan:
Saat menangani pemuatan asinkron di SwiftUI, kesulitan sebenarnya adalah menjaga siklus hidup tugas, validitas hasil, dan aliran status halaman tetap konsisten.
Selama ketiga hal ini tidak dilakukan, halaman akan terus berkembang:
- Ulangi permintaan
- Tulis kembali hasil lama
- memuat kebingungan
Masalah ini biasanya tidak dapat diperbaiki dengan menulis beberapa Task lagi.
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