Dart Dilinde Asenkron Programlama (Asynchronous)
Dart dilinde asenkron programlama, bir işlemin bitmesini beklemek yerine programın çalışmasına izin veren yapıdır.
Dart Dilinde Asenkron Programlama
Dart programlama dilinde kodlar aksi belirtilmediği sürece yukarıdan aşağıya doğru olacak şekilde işlenir ve bir satırdaki işlem bitmeden diğer satıra geçilmez. Bu şekilde yazılan kodların oluşturduğu yapıya ise senkron yapı denilmektedir.
main() {
print ("1. işlem çalıştı.");
print ("2. işlem çalıştı.");
print ("3. işlem çalıştı.");
}
Senkronize kelimesinin sözlük anlamına bakıldığında, aynı zamanda çalışan, eş zamanlı çalışan sistemler gibi anlamlara geldiği görülmektedir. Kelimenin anlamı nedeniyle yukarıda yazılan kodların aynı anda çalıştığı gibi bir izlenim oluşmamalı. Zira burada kast edilen anlam, senkronize olmasa da senkronize bir sistemmiş gibi çok yakın bir sonuç vermesinden ötürü senkronize kabul edildiğine vurgu yapıldığıdır.
Yani yukarıdaki print (“1. işlem çalıştı.”); ile print (“2. işlem çalıştı.”); kodları neredeyse aynı zamanda sonuç vermektedir. Ancak birinci kodumuz çalışmadan asla ikinci kod çalışmamaktadır.
Eğer gerçekten sözlük anlamıyla bir senkronizasyon olsaydı tüm kodlarımız aynı anda çalışırdı. Dart single threaded yapıda bir programlama dili olduğu için yazılan kodlarımız aynı anda çalışmaz.
Yukarıdaki örneğimizi biraz modifiye ettiğimizde aslında onların çalışmaya aynı anda başlamadığı net bir şekilde görülecektir.
main() {
print ("1. işlem çalıştı.");
var toplam = 0;
for (var i = 0; i<50000; i++){
toplam = toplam + i;
}
print ("3. işlem çalıştı.");
}
Yukarıdaki kodu çalıştırdığımızda fark edeceğiniz üzere yazdığımız for döngüsü, senkronize ortamı bozan bir kod olmuş oldu, çünkü bariz bir şekilde gecikmeye yol açan bir içeriğe sahip. Dolayısıyla da işlemin uzun sürmesi bir nevi donma, kasılma olarak bahsedilen olayların yaşanmasına sebep oldu. Yani, 3. kodumuz o esnada çalışmayı beklerken bir türlü ikinci kodun hesaplamasının bitmemesi nedeniyle tabiri cazise sisteme baskı uygulamakta ve bu da donmaya yol açmakta.
Başta demiştik ki aksi belirtilmediği sürece yukarıdan aşağıya doğru olacak şekilde işlenir. Ancak 3. kodumuz 2. kodun bitmesini beklerken sistemde donmalara sebep olduğu için bizim bu sorunu aşmamız gerekir. İşte bu sorunu asenkron (eş zamansız) programlamayla aşmaktayız. Programlamada bu terim, kodların parçalara ayrılıp ilgili işlemlerin birbirini beklemeden aynı anda sürdürülmesini sağlar.
main() {
print ("birinci işlem çalıştı.");
Future.microtask((){
var toplam = 0;
for (var i = 0; i<50000; i++){
toplam = toplam + i;
}
print ("Toplam: $toplam");
});
print ("üçüncü. işlem çalıştı.");
}
Çıktı:
birinci işlem çalıştı.
üçüncü. işlem çalıştı.
Toplam: 1249975000
Yukarıda bahsettiğimiz durumun yaşanmaması adına, gecikmeli işlemlere sebep olabilecek kodlarımızı future nesnesi adında ileride bitecek işlemleri temsil eden bir sınıf (class) içine yazarız. Bu sayede oldukça düzgün bir şekilde kodlama yaklaşımını da sergilemiş oluruz.
Dart’ta async – await
Yukarıdaki örneğimizde for döngüsü olan kodumuz gecikmeli bir işlem içerdiği için önce birinci sonra üçüncü ve son olarak da gecikmeli işlemimizin olduğu ikinci kodumuzu çalıştırdık. Ancak bazı durumlarda biz gecikmeli işlemimizin olduğu kod bloğunu çalıştırdıktan sonra diğer kodlarımızı çalıştırmamız gerekli olabilir.
İşte böylesi bir durumu async ve await ile sağlayabiliriz. Böylece gecikmeli kodumuzu yazdığımız alanın donmalara yol açmaması adına sonraki kodlara tabiri caizse bekleme emri verilir.
main() async{
print ("birinci. işlem çalıştı.");
await Future.microtask((){
var toplam = 0;
for (var i = 0; i<50000; i++){
toplam = toplam + i;
}
print ("toplam: $toplam");
});
print ("üçüncü. işlem çalıştı.");
}
Çıktı:
birinci. işlem çalıştı.
toplam: 1249975000
üçüncü. işlem çalıştı.
Kodu çalıştırmak için: DartPad