Основы дартс (Часть 1: Фьючерсы) | Кодементор
Первоначально опубликовано 8 июня 2019 г.
Целевая аудитория: Новичок
Введение
Изучите основы языка программирования Dart. Flutter использует Dart для создания потрясающих кроссплатформенных мобильных и веб-приложений. В этом уроке я расскажу о двух функциях языка Dart ниже:
- Часть-1 (текущая) Фьючерсы: асинхронное программирование с помощью Dart
- Часть 2 Потоки: асинхронное программирование с помощью Dart
Фьючерсы: асинхронное программирование с помощью Dart
«Фьючерсы» — это объекты Future, представляющие результаты асинхронных операций. Асинхронные операции не блокируют поток, и их обработка завершается позже. Результаты асинхронных операций возвращаются как Futures
. Функции, которые выполняют дорогостоящую работу, должны использовать асинхронную модель для выполнения своей работы. Будущий объект представляется как Future<T>
где T — тип результатов, возвращаемых дорогостоящей операцией.
Асинхронные операции в Dart можно реализовать двумя способами:
- С использованием
await
а такжеasync
- С использованием
Future
API.
await
а также async
await
а также async
ключевые слова используются вместе. Функция, которая должна выполнять дорогостоящую работу, будет помечена ключевым словом async
. Внутри функции дорогостоящий вызов имеет префикс ключевого слова await
. Программа приостанавливается, когда await
вызывается или функция возвращает значение или достигает конца функции.
Давайте посмотрим в следующем фрагменте кода, как async
а также await
используются ключевые слова. await
может вызываться только в функции, которая помечена/объявлена как async
. Future
ключевое слово перед функцией makeDataCall()
означает, что эта функция будет выполняться асинхронно и будет приостановлена при обнаружении await
.
import 'dart:async';
const data = "I'm expansive data";
//Asynchronous function that makes the expensive
//data call
Future<void> makeDataCall() async {
var data = await getData();
print(data);
}
//Expensive function that could be long running
//in real world.
String getData() {
return data;
}
//Entry point function
void main() {
makeDataCall();
}
Обработка ошибок (блок try/catch)
Когда в блоке try возникает исключение, блок catch выполняет его код. Обработка ошибок для асинхронного и синхронного кода выполняется аналогичным образом.
Давайте добавим блок try/catch в предыдущий код и посмотрим, как он будет выглядеть сейчас. я бросаю Exception
специально в try
блок, чтобы продемонстрировать точку здесь.
import 'dart:async';
const data = "I'm expansive data";
//Asynchronous funtion that makes the expensive
//data call
Future<void> makeDataCall() async {
try {
var data = await getData();
throw Exception(
"Error occurred in fetching data");
} catch(e) {
print(e.toString());
}
}
//Expensive function that could be long running
//in real world.
String getData() {
return data;
}
//Entry point function
void main() {
makeDataCall();
}
Последовательность вызовов функций
Управлять порядком выполнения асинхронных функций можно с помощью секвенирования с помощью await
а также async
. Давайте посмотрим, как это делается на примере ниже.
import 'dart:async';
const data = "I'm expansive data";
void getDataA() {
print("dataA");
}
void getDataB() {
print("dataB");
}
String getDataC() {
return "dataC";
}
void printMyData(String data) {
print(data);
}
//Entry point function
main() async {
//order matters.
//Functions will execute in the order they are called.
await getDataA();
await getDataB();
//getDataC() will execute first and will
//pass its data into printMyData
printMyData(await getDataC());
}
Future
API
В Future
API, then()
метод используется для регистрации обратного вызова, который срабатывает по завершении Future
.
Пример ниже преобразует наш предыдущий пример кода await
а также async
в Future
API. Следите за использованием then()
в main()
функция.
import 'dart:async';
const data = "I'm expansive data";
//Future with String data is being returned.
//This function returns the instance of
//Future and not the actual data.
Future<String> makeDataCall() async {
var data = await getData();
return data;
}
String getData() {
return data;
}
void main() {
var theFuture = makeDataCall();
//then() is called at the instance of Future
theFuture.then((value) {
print(value);
});
}
Давайте рассмотрим еще один пример Future
API. В этом примере Future
ничего не возвращает и выглядит так Future<void>
. В таком случае, then()
обратный вызов будет использовать unused argument
представленный как _
условно. Ознакомьтесь с приведенным ниже фрагментом кода, чтобы увидеть его в действии.
import 'dart:async';
const data = "I'm expansive data";
//Future doesn't return anything
Future<void> makeDataCall() async {
var data = await getData();
print(data);
}
String getData() {
return data;
}
void main() {
var theFuture = makeDataCall();
//then() uses underscore as unused argument.
theFuture.then((_) {
//_ is not used
print("There's nothing to be printed here. Work is already done.");
});
}
Обработка ошибок — Future
API
Future
API использует цепочку для обработки исключений. Ошибка перехватывается и обрабатывается в catchError()
блокировать. catchError()
прикован к then()
метод.
import 'dart:async';
const data = "I'm expansive data";
//Future with String data is being returned.
//This function returns the instance of
//Future and not the actual data.
Future<String> makeDataCall() async {
var data = await getData();
//return data;
throw Exception("Error occurred in making data call");
}
String getData() {
return data;
}
void main() {
var theFuture = makeDataCall();
//Error is caught and handled in catchError block
theFuture.then((value) {
print(value);
}).catchError((error){
print(error);});
}
Использование Future.wait()
Future.wait()
используется, когда необходимо выполнить несколько асинхронных функций перед вызовом другой функции. Это может быть полезно, когда для следующего шага необходимы данные из нескольких источников/функций.
import 'dart:async';
String getData(data) {
return data;
}
Future<String> getDataA() async {
var data = await getData("dataA");
return data;
}
Future<String> getDataB() async {
var data = await getData("dataB");
return data;
}
Future<String> getDataC() async {
var data = await getData("dataC");
return data;
}
void printMyData(List<String> data) {
print(data);
}
//Entry point function
main() async {
await Future.wait([getDataA(), getDataB(), getDataC()])
.then((List responses) => printMyData(responses))
.catchError((error){});
}
Использованная литература:
Удачной готовки с Dart и Flutter
Понравилась статья?
Не нашли интересующую вас тему? Пожалуйста, оставляйте комментарии или пишите мне по электронной почте о темах, которые вы хотели бы, чтобы я написал!
Кстати, я люблю кексы и кофе