Dart Futures, Async, Await ufak açıklamalar

Gauloran

Moderasyon Ekibi Lideri
7 Tem 2013
8,198
672
Bu konuda Future, async, await gibi kavramları anlamak için ufak bir çalışma yapıyoruz. Öncelikle yeni bir flutter projesi oluşturun.

lib/
explain_futures.dart
main.dart
second_page.dart

başlangıç olarak bu dosyaları koyun kodlar:

main.dart
Kod:
import 'package:flutter/material.dart';
import 'package:futuresfalan/explain_futures.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const ExplainFutures(),
    );
  }
}

explain_futures.dart
Kod:
import 'package:flutter/material.dart';

class ExplainFutures extends StatefulWidget {
  const ExplainFutures({super.key});

  @override
  State<ExplainFutures> createState() => _ExplainFuturesState();
}

class _ExplainFuturesState extends State<ExplainFutures> {

  @override
  void initState() {
   
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text(
          'Futures explained!',
          style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
        ),
      ),
    );
  }
}

second_page.dart

Kod:
import 'package:flutter/material.dart';

class SecondPage extends StatelessWidget {
  const SecondPage({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text('Second Page'),
      ),
    );
  }
}

devam edelim öncelikle anlamak için bize bir json verisi lazım dummy şekilde https://jsonplaceholder.typicode.com/users burada kullanıcılarla ilgili dummy bir json verisi bulunuyor. şimdi explain_futures.dart dosyasına gelip initState metoduna bakalım. initState içerisinde async await tarzı şeyler olmaz. initState'in kendisine baktığınızda da void typetır. Bu nedenle initState'de bir şeyler yapmak istediğimizde bir fonksiyon yazıp o fonksiyonu initState'de kullanmak mantıklıdır. Bunu yapmadan önce projemize http package'ını yükleyelim.


Kod:
$ dart pub add http

şimdi yukarıda verdiğim url'e bir get isteği gönderebiliriz.

Kod:
class _ExplainFuturesState extends State<ExplainFutures> {
  @override
  void initState() {
    ogrenciDetaylariniGetir();
    super.initState();
  }

  ogrenciDetaylariniGetir() {
    const url = "https://jsonplaceholder.typicode.com/users";
    http.get(Uri.parse(url));
  }

url'i direkt olarak http.get(url) şeklinde veremiyoruz Uri.parse kullanmamız gerekiyor çünkü Future<Response> get(Uri url, {Map<String, String>? headers}) http'nin get metodu bizden Uri url bekliyor ondan dolayı bir url'i de Uri.parse diyerek Uri şeklinde verebiliyoruz.

Future<Response> get(Uri url, {Map<String, String>? headers})

incelediğimizde http'nin get metodu Future döndüren bir metod yani ilk başta boş olabilir daha sonradan doluluk olabilir gibi düşünebiliriz. Bu tür zaman alabilen işlemlerimizde Futureları kullanıyoruz.

o yüzden cevap'ı const yapmadık.

Kod:
class _ExplainFuturesState extends State<ExplainFutures> {
  @override
  void initState() {
    ogrenciDetaylariniGetir();
    super.initState();
  }

  ogrenciDetaylariniGetir() {
    const url = "https://jsonplaceholder.typicode.com/users";
    final cevap = http.get(Uri.parse(url));
    print(cevap);
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
  }

ancak böyle yaptığımızda hiçbir şey yazdıramadık amacımız get isteği attığımız urldeki json datasını yazdırmaktı. Bunu yapabilmek için 2 yaklaşım var 1.then yaklaşımı diyebiliriz

Kod:
ogrenciDetaylariniGetir() {
    const url = "https://jsonplaceholder.typicode.com/users";
    http.get(Uri.parse(url)).then((value) => print(value.body));
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
  }

yaparsak url'ye git ardından Future olayının sonunda future'ın bize ne döndürdüğünü al yani döndürülen şeyi ve bunun body'sini yazdır dediğimizde
url'deki datayı çekiyoruz.

frTktj.png


hata çıktığında o hatayı yakalayıp nasıl yazdırabiliriz aslında basitçe

Kod:
class _ExplainFuturesState extends State<ExplainFutures> {
  @override
  void initState() {
    ogrenciDetaylariniGetir();
    super.initState();
  }

  ogrenciDetaylariniGetir() {
    const url = "https://jsonplaceholder.typicode.com/users";
    http.get(Uri.parse(url)).then((value) => print(value.body)).catchError((err)=>print(err.toString()));
  }

ama bu yaklaşım çalışsa da çok da iyi bir yaklaşım değil yapacağınız 10-15 tane daha benzer işlem olduğunda kodlar karışır.

Kod:
ogrenciDetaylariniGetir() async {
    const url = "https://jsonplaceholder.typicode.com/users";
    //http.get(Uri.parse(url)).then((value) => print(value.body)).catchError((err)=>print(err.toString()));
    http.Response cvp = await http.get(Uri.parse(url));
    print(cvp.body);
  }

Şimdi http packageından Response turunde bir cevap geleceği için o turde bir cvp oluşturup http'nin get metodunu kullanarak urldeki datayı çekiyoruz ancak bunu yaparken başa await atmazsanız hata alırsınız. awaitin yaptığı iş ise sonuçta http'nin get metodu bir Future döndürüyor yani Future<Response> döndürüyor fakat sizin cvp olarak tanımladığınız şey sadece Response. awaitin yaptığı iş ise cevabı alır o süreci bekletir ve Future<Response> 'ın Response'ını alır. Böylece cvp.body diyerek yazdırabilirsiniz çektiğiniz datayı. Ancak hata yakalama yapmayı unuttuk.

Kod:
 Future<String> ogrenciDetaylariniGetir() async {
    const url = "https://jsonplaceholder.typicode.com/users";
    //http.get(Uri.parse(url)).then((value) => print(value.body)).catchError((err)=>print(err.toString()));

    try {
      http.Response cvp = await http.get(Uri.parse(url));
      print(cvp.body);
    } catch (err) {
      print(err.toString);
    }

   
  }

try catch yaparak basitçe hata yakalama yapabiliyoruz. Uygulamada delay oluşturmayı da Future sayesinde yapabiliriz. Second_page'e gidelim 2 saniye sonra

Kod:
  geciktirme() async {
    //2 sn beklet sayfa degis
    await Future.delayed(const Duration(seconds: 2), () {
      Navigator.of(context).push(MaterialPageRoute(
        builder: (context) => const SecondPage(),
      ));
    });
  }

şöyle şeyler de yapabilirsiniz

Kod:
 void initState() {
    //ogrenciDetaylariniGetir();
    //geciktirme();
    benimFuturePaketim();
    super.initState();
  }

  benimFuturePaketim() async {
    Future future = Future(() {
      print('slm naber');
      return 'şşT';
    });

    future.then((value) => print(value)).catchError((err) => print(err.toString()));
  }

hata oluşturmayı da yani future error oluşturup onu yakalayabilirsiniz

Kod:
try {
      await Future.error(throw Exception('hatalar'));
    } catch (err) {
      print(err.toString());
    }
  }

bu tür Futurelarla çalışırken FutureBuilder kullanımı önemlidir çok fazla kolaylık sağlar sonraki konuda görüşürüz.

Ayrıca bkz:

0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #1
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #2
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #3
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #4
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #5
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #6
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #7
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #8
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #9
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #10
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #11
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #12
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #13
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #14
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #15
Flutter & Dart Fundamentals | Örnek Quiz Uygulaması #16
Flutter uygulamalarında debugging mantığı #17
Flutter element tree render tree mantığı
Flutter cubit mantığı fonksiyon ve event bazlı yaklaşım
Baştan sona Twitter'ı yazalım #1 (Flutter, Riverpod, Fpdart, Appwrite)
 

GHOSTJEONSA

Yeni üye
5 May 2020
43
21
Bu konuda Future, async, await gibi kavramları anlamak için ufak bir çalışma yapıyoruz. Öncelikle yeni bir flutter projesi oluşturun.

lib/
explain_futures.dart
main.dart
second_page.dart

başlangıç olarak bu dosyaları koyun kodlar:

main.dart
Kod:
import 'package:flutter/material.dart';
import 'package:futuresfalan/explain_futures.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const ExplainFutures(),
    );
  }
}

explain_futures.dart
Kod:
import 'package:flutter/material.dart';

class ExplainFutures extends StatefulWidget {
  const ExplainFutures({super.key});

  @override
  State<ExplainFutures> createState() => _ExplainFuturesState();
}

class _ExplainFuturesState extends State<ExplainFutures> {

  @override
  void initState() {
  
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text(
          'Futures explained!',
          style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
        ),
      ),
    );
  }
}

second_page.dart

Kod:
import 'package:flutter/material.dart';

class SecondPage extends StatelessWidget {
  const SecondPage({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text('Second Page'),
      ),
    );
  }
}

devam edelim öncelikle anlamak için bize bir json verisi lazım dummy şekilde https://jsonplaceholder.typicode.com/users burada kullanıcılarla ilgili dummy bir json verisi bulunuyor. şimdi explain_futures.dart dosyasına gelip initState metoduna bakalım. initState içerisinde async await tarzı şeyler olmaz. initState'in kendisine baktığınızda da void typetır. Bu nedenle initState'de bir şeyler yapmak istediğimizde bir fonksiyon yazıp o fonksiyonu initState'de kullanmak mantıklıdır. Bunu yapmadan önce projemize http package'ını yükleyelim.


Kod:
$ dart pub add http

şimdi yukarıda verdiğim url'e bir get isteği gönderebiliriz.

Kod:
class _ExplainFuturesState extends State<ExplainFutures> {
  @override
  void initState() {
    ogrenciDetaylariniGetir();
    super.initState();
  }

  ogrenciDetaylariniGetir() {
    const url = "https://jsonplaceholder.typicode.com/users";
    http.get(Uri.parse(url));
  }

url'i direkt olarak http.get(url) şeklinde veremiyoruz Uri.parse kullanmamız gerekiyor çünkü Future<Response> get(Uri url, {Map<String, String>? headers}) http'nin get metodu bizden Uri url bekliyor ondan dolayı bir url'i de Uri.parse diyerek Uri şeklinde verebiliyoruz.

Future<Response> get(Uri url, {Map<String, String>? headers})

incelediğimizde http'nin get metodu Future döndüren bir metod yani ilk başta boş olabilir daha sonradan doluluk olabilir gibi düşünebiliriz. Bu tür zaman alabilen işlemlerimizde Futureları kullanıyoruz.

o yüzden cevap'ı const yapmadık.

Kod:
class _ExplainFuturesState extends State<ExplainFutures> {
  @override
  void initState() {
    ogrenciDetaylariniGetir();
    super.initState();
  }

  ogrenciDetaylariniGetir() {
    const url = "https://jsonplaceholder.typicode.com/users";
    final cevap = http.get(Uri.parse(url));
    print(cevap);
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
  }

ancak böyle yaptığımızda hiçbir şey yazdıramadık amacımız get isteği attığımız urldeki json datasını yazdırmaktı. Bunu yapabilmek için 2 yaklaşım var 1.then yaklaşımı diyebiliriz

Kod:
ogrenciDetaylariniGetir() {
    const url = "https://jsonplaceholder.typicode.com/users";
    http.get(Uri.parse(url)).then((value) => print(value.body));
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
  }

yaparsak url'ye git ardından Future olayının sonunda future'ın bize ne döndürdüğünü al yani döndürülen şeyi ve bunun body'sini yazdır dediğimizde
url'deki datayı çekiyoruz.

frTktj.png


hata çıktığında o hatayı yakalayıp nasıl yazdırabiliriz aslında basitçe

Kod:
class _ExplainFuturesState extends State<ExplainFutures> {
  @override
  void initState() {
    ogrenciDetaylariniGetir();
    super.initState();
  }

  ogrenciDetaylariniGetir() {
    const url = "https://jsonplaceholder.typicode.com/users";
    http.get(Uri.parse(url)).then((value) => print(value.body)).catchError((err)=>print(err.toString()));
  }

ama bu yaklaşım çalışsa da çok da iyi bir yaklaşım değil yapacağınız 10-15 tane daha benzer işlem olduğunda kodlar karışır.

Kod:
ogrenciDetaylariniGetir() async {
    const url = "https://jsonplaceholder.typicode.com/users";
    //http.get(Uri.parse(url)).then((value) => print(value.body)).catchError((err)=>print(err.toString()));
    http.Response cvp = await http.get(Uri.parse(url));
    print(cvp.body);
  }

Şimdi http packageından Response turunde bir cevap geleceği için o turde bir cvp oluşturup http'nin get metodunu kullanarak urldeki datayı çekiyoruz ancak bunu yaparken başa await atmazsanız hata alırsınız. awaitin yaptığı iş ise sonuçta http'nin get metodu bir Future döndürüyor yani Future<Response> döndürüyor fakat sizin cvp olarak tanımladığınız şey sadece Response. awaitin yaptığı iş ise cevabı alır o süreci bekletir ve Future<Response> 'ın Response'ını alır. Böylece cvp.body diyerek yazdırabilirsiniz çektiğiniz datayı. Ancak hata yakalama yapmayı unuttuk.

Kod:
 Future<String> ogrenciDetaylariniGetir() async {
    const url = "https://jsonplaceholder.typicode.com/users";
    //http.get(Uri.parse(url)).then((value) => print(value.body)).catchError((err)=>print(err.toString()));

    try {
      http.Response cvp = await http.get(Uri.parse(url));
      print(cvp.body);
    } catch (err) {
      print(err.toString);
    }

  
  }

try catch yaparak basitçe hata yakalama yapabiliyoruz. Uygulamada delay oluşturmayı da Future sayesinde yapabiliriz. Second_page'e gidelim 2 saniye sonra

Kod:
  geciktirme() async {
    //2 sn beklet sayfa degis
    await Future.delayed(const Duration(seconds: 2), () {
      Navigator.of(context).push(MaterialPageRoute(
        builder: (context) => const SecondPage(),
      ));
    });
  }

şöyle şeyler de yapabilirsiniz

Kod:
 void initState() {
    //ogrenciDetaylariniGetir();
    //geciktirme();
    benimFuturePaketim();
    super.initState();
  }

  benimFuturePaketim() async {
    Future future = Future(() {
      print('slm naber');
      return 'şşT';
    });

    future.then((value) => print(value)).catchError((err) => print(err.toString()));
  }

hata oluşturmayı da yani future error oluşturup onu yakalayabilirsiniz

Kod:
try {
      await Future.error(throw Exception('hatalar'));
    } catch (err) {
      print(err.toString());
    }
  }

bu tür Futurelarla çalışırken FutureBuilder kullanımı önemlidir çok fazla kolaylık sağlar sonraki konuda görüşürüz.

Ayrıca bkz:

0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #1
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #2
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #3
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #4
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #5
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #6
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #7
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #8
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #9
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #10
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #11
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #12
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #13
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #14
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #15
Flutter & Dart Fundamentals | Örnek Quiz Uygulaması #16
Flutter uygulamalarında debugging mantığı #17
Flutter element tree render tree mantığı
Flutter cubit mantığı fonksiyon ve event bazlı yaklaşım
Baştan sona Twitter'ı yazalım #1 (Flutter, Riverpod, Fpdart, Appwrite)
Emeğine sağlık
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.