Dart'ta Hata Yönetimi: Try-Catch ve Asenkron İşlemler
Hata Yönetimi ve Asenkron Programlama
Bugün iki önemli konuyu öğrendim: Hata yönetimi (Try-Catch) ve asenkron işlemler (Async-Await). İkisi de gerçek uygulamalarda çok kritik konular.
Canlı Demo: Try-Catch ve Async-Await
Hata yönetimi ve asenkron programlamayı interaktif olarak öğrenin:
Try-Catch - Hataları Yakalamak
Programlarımız her zaman kusursuz çalışmıyor. Kullanıcı yanlış bir şey girebilir, internet bağlantısı kopabilir, dosya bulunamayabilir. İşte Try-Catch tam da bu durumlar için.
İlk Karşılaştığım Problem
Kullanıcıdan sayı istiyorum ama kullanıcı harf giriyor. Program çöküyor:
import 'dart:io';
void main() {
print("Bir sayı girin:");
String girdi = stdin.readLineSync()!;
int sayi = int.parse(girdi); // Eğer harf girerse HATA!
print("Girdiğiniz sayı: $sayi");
}Kullanıcı "abc" yazarsa program patlar. Çözüm? Try-Catch!
Try-Catch ile Güvenli Hale Getirme
import 'dart:io';
void main() {
print("Bir sayı girin:");
try {
String girdi = stdin.readLineSync()!;
int sayi = int.parse(girdi);
print("Girdiğiniz sayı: $sayi");
} catch (e) {
print("Hata! Lütfen geçerli bir sayı girin.");
print("Hata detayı: $e");
}
}Şimdi kullanıcı ne yazarsa yazsın program çökmüyor. Hata olursa catch bloğu çalışıyor.
Sürekli Sayı İsteyen Program
Ben bunu bir adım ileri götürdüm. Kullanıcı doğru sayı girene kadar tekrar tekrar sor:
import 'dart:io';
void main() {
int sayi;
while (true) {
try {
print("Bir sayı girin:");
sayi = int.parse(stdin.readLineSync()!);
break; // Başarılıysa döngüden çık
} catch (e) {
print("Lütfen geçerli bir sayı giriniz!");
}
}
print("Tebrikler! Girdiğiniz sayı: $sayi");
}Bu kod kullanıcı doğru sayı girene kadar devam ediyor. Çok kullanışlı!
Finally Bloğu
Bazen hata olsa da olmasa da çalışmasını istediğiniz kod olabilir:
try {
// Riskli işlem
int sonuc = 10 ~/ 0; // Sıfıra bölme hatası
} catch (e) {
print("Hata oluştu: $e");
} finally {
print("Bu her zaman çalışır");
}finally bloğu ne olursa olsun çalışır. Genelde dosya kapatma, bağlantı kesme gibi işler için kullanılır.
Asenkron İşlemler - Async ve Await
Asenkron programlama konusu beni başta çok zorladı. Ama şöyle anladım: Bazı işlemler zaman alıyor (internet'ten veri çekme, dosya okuma vb.) ve bu işlemleri beklerken programın donmasını istemiyoruz.
Senkron vs Asenkron
Senkron (Normal):
İşlem 1 başla → İşlem 1 bitir → İşlem 2 başla → İşlem 2 bitirAsenkron:
İşlem 1 başla → İşlem 2 başla → İşlem 1 bitir → İşlem 2 bitirYani bir şey beklerken diğer şeyleri de yapabiliyorsunuz.
Future, Async, Await - Üçlü Kavram
Bu üç kelime hep birlikte kullanılıyor:
- Future: Gelecekte tamamlanacak bir işlem
- async: Fonksiyonun asenkron olduğunu belirtir
- await: İşlem bitene kadar bekle
İlk Async Örneğim
Future<void> main() async {
print("Veri bekleniyor...");
String veri = await veritabanindanVeriAl();
print("Veri alındı: $veri");
}
Future<String> veritabanindanVeriAl() async {
// 3 saniye bekle (veritabanını simüle ediyoruz)
await Future.delayed(Duration(seconds: 3));
return "Kullanıcı verileri";
}Bu kod şöyle çalışıyor:
- "Veri bekleniyor..." yazdır
veritabanindanVeriAl()fonksiyonunu çağır ve bekle (3 saniye)- Veri gelince "Veri alındı: ..." yazdır
Await Kullanmazsak Ne Olur?
Future<void> main() async {
print("Veri bekleniyor...");
String veri = veritabanindanVeriAl(); // HATA!
print("Veri alındı: $veri");
}Bu çalışmaz çünkü veritabanindanVeriAl() hemen değer döndürmüyor, bir Future döndürüyor. await kullanmadan Future'ı String'e çeviremezsiniz.
Daha Gerçekçi Bir Örnek
Future<void> main() async {
print("1. Veri bekleniyor...");
var veri = await veritabanindanVeriAl();
print("2. Veri alınıyor: $veri");
}
Future<String> veritabanindanVeriAl() async {
// Her saniye yükleme durumunu göster
for (var i = 1; i <= 5; i++) {
await Future.delayed(
Duration(seconds: 1),
() => print("Yükleniyor... %${i * 20}")
);
}
return "Veritabanı kümesi";
}Çıktı:
1. Veri bekleniyor...
Yükleniyor... %20
Yükleniyor... %40
Yükleniyor... %60
Yükleniyor... %80
Yükleniyor... %100
2. Veri alınıyor: Veritabanı kümesiTry-Catch ile Async Kullanımı
Asenkron işlemlerde de hata olabilir (internet kesildi, timeout vb.):
Future<void> main() async {
try {
print("API'den veri çekiliyor...");
String veri = await apidenVeriCek();
print("Veri: $veri");
} catch (e) {
print("Hata oluştu: $e");
print("İnternet bağlantınızı kontrol edin");
}
}
Future<String> apidenVeriCek() async {
await Future.delayed(Duration(seconds: 2));
// Hata simülasyonu
throw Exception("Sunucuya bağlanılamadı!");
// return "API Verisi"; // Normalde bu çalışırdı
}Flutter'da Kullanım
Flutter'da sürekli async kullanıyoruz. Çünkü:
- API'lerden veri çekiyoruz
- Veritabanı işlemleri yapıyoruz
- Dosya okuyoruz
- Kullanıcı girişi bekliyoruz
Flutter'da API Çağrısı Örneği
class VeriSayfasi extends StatefulWidget {
@override
_VeriSayfasiState createState() => _VeriSayfasiState();
}
class _VeriSayfasiState extends State<VeriSayfasi> {
String veri = "Yükleniyor...";
@override
void initState() {
super.initState();
verileriYukle();
}
Future<void> verileriYukle() async {
try {
// API çağrısı yap (örnek)
await Future.delayed(Duration(seconds: 2));
setState(() {
veri = "Veriler başarıyla yüklendi!";
});
} catch (e) {
setState(() {
veri = "Hata: $e";
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text(veri),
),
);
}
}FutureBuilder Widget'ı
Flutter'da Future'ları göstermek için özel bir widget var:
FutureBuilder<String>(
future: veritabanindanVeriAl(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator(); // Loading göster
}
if (snapshot.hasError) {
return Text("Hata: ${snapshot.error}"); // Hata göster
}
return Text("Veri: ${snapshot.data}"); // Veri göster
},
)Bu widget otomatik olarak loading, hata ve başarı durumlarını yönetiyor. Çok kullanışlı!
Async-Await Kullanırken Dikkat Edilecekler
Öğrendiğim bazı önemli kurallar:
- await sadece async fonksiyonlarda kullanılır
// YANLIŞ
void fonksiyon() {
await birSey(); // HATA!
}
// DOĞRU
Future<void> fonksiyon() async {
await birSey(); // Tamam
}- async fonksiyon mutlaka Future döndürür
Future<String> veriAl() async {
return "Veri";
}- Birden fazla await kullanabilirsiniz
Future<void> tumVerileriAl() async {
String veri1 = await api1denVeriAl();
String veri2 = await api2denVeriAl();
String veri3 = await api3denVeriAl();
print("$veri1, $veri2, $veri3");
}- Paralel çalıştırmak için Future.wait
Future<void> parallelVeriler() async {
// Üçü aynı anda başlar
var sonuclar = await Future.wait([
api1denVeriAl(),
api2denVeriAl(),
api3denVeriAl(),
]);
print(sonuclar); // [veri1, veri2, veri3]
}Bugün Ne Öğrendim?
- Try-Catch ile hataları güvenli şekilde yakalıyoruz
- Finally bloğu her durumda çalışır
- Async-Await ile asenkron işlemleri yönetiyoruz
- Future gelecekte tamamlanacak işlemler için
- Flutter'da FutureBuilder çok işe yarıyor
Yarın Flutter'ın UI yapısına (Widget ağacı, Row, Column, Stack) bakacağım. Artık kod tarafını iyi öğrendim, şimdi arayüz zamanı!
Sorularınız mı var?
Kodlamaya devam! 🚀