3.0 Асинхронность. async и await
Синтаксический сахар, появившийся в 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 для начала вернет обещание вернуть результат, а после выполнения вернет его.
Таким образом у нас возникает потребность дождаться результата:
Добавим в call, main ключевое
async.
"Дождемся" результат функции
getEmploye()
"Дождемся" результат функции
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/
Как тебе это статья? Пиши в комментариях, мы хотим развиваться:)