Pull to refresh

3.0 Асинхронность. async и await

Level of difficultyMedium
Reading time3 min
Views4.1K

Синтаксический сахар, появившийся в Dart 1.9 async и await это декларативный способ определения асинхронных функций, они помогают убрать громоздкие конструкции и повысить читабельность кода.

  • async: ключевое слово перед телом функции, чтобы пометить ее как асинхронную.

    void main() async { ··· }

  • async функция: это функция, помеченная async ключевым словом. Тогда в ней можно использовать await.

    Future<String> main() async { ··· }

  • await: ключевое слово для получения завершенного результата асинхронного кода, сообщает о том что нужно подождать результата этой операцииawait работает только внутри async функции.

    print(await GetPosts());

Возможно появиться вопрос о том зачем же нам ждать результат, рассмотрим пример:

 call() {
  var emp = getEmploye();
  return 'на звонок ответил: $emp';
}

Future<String> getEmploye() =>
    Future.delayed(
      const Duration(seconds: 2),
      () => 'дядя Петя',
    );

void main() {
  print('Звоню в отдел...');
  print(call());
}
Консоль
Консоль

Из-за того что получение результата происходит до того как мы печатаем переменную emp мы видим Instance of '_Future<String>' \ . Future для начала вернет обещание вернуть результат, а после выполнения вернет его.

Таким образом у нас возникает потребность дождаться результата:

  1. Добавим в call, main ключевое async.

  2. "Дождемся" результат функции getEmploye()

  3. "Дождемся" результат функции call() в main

 call() async{
  var emp = await getEmploye();
  return 'на звонок ответил: $emp';
}

Future<String> getEmploye() =>
    Future.delayed(
      const Duration(seconds: 2),
      () => 'дядя Петя',
    );

void main() async{
  print('Звоню в отдел...');
  print(await call());
}
Консоль
Консоль

До Dart 1.9, использовали метод then()для регистрации обратного вызова. Этот обратный вызов сработает, когда фьюча завершалась:

  void main () {
  print('start');
  Message();
  print("Выполнение функции main");
}


void Message() {
    print("Начало функции Message");
    Future<String> messageFuture = getMessage();
    messageFuture.then((val){
        print("Получено сообщение: $val");
    }).then((val){print('end');});
    print("Завершение функции Message");
}
 
Future<String> getMessage() {
  return Future.delayed(Duration(seconds: 3), () => "Доброе утро");
}

Вот пример с then вместо async await, уже в таком простом коде мы можем почувствовать сложности в определения последовательности кода.

Особенно в контрасте с async await:

Future<void>  Message() async {
  print('start');
    print("Начало функции  Message");
    String message = await getMessage();
    print("Получено сообщение: $message");
    print("Завершение функции  Message");
  print('end');
}
 
Future<String> getMessage() {
  return Future.delayed(Duration(seconds: 3), () => "Доброе утро");
}
 
void main () {
   Message();
  print("Выполнение функции main");
}

Такой код легче читать и писать. И так, мы поняли что нам все таки нужны async await.

Ловим красного кота

Обработка ошибок

 call() async{
 try {
  var emp = await getEmploye();
  return 'на звонок ответил: $emp';

  } catch (e) {
    // handle error...
  }
}

Eсли вtry возникает исключение, запускается код внутри catch.

Рекомендации

На основе трех статей из этой серии ты можешь потренироваться:

https://dart.dev/codelabs/async-await

Рекомендую к прочтению:

https://metanit.com/dart/tutorial/7.3.php

https://youtu.be/5AxWC49ZMzs на англ от Flutter Team обязательно посмотри, хотя бы с переводчиком или субтитрами, в следующей статье мы будем разбирать темы, затрагиваемые в этом видео.

https://habr.com/ru/articles/442282/

Как тебе это статья? Пиши в комментариях, мы хотим развиваться:)

Tags:
Hubs:
Total votes 7: ↑4 and ↓3+1
Comments3

Articles