Pull to refresh

Dart: Асинхронность

Level of difficultyEasy
Reading time3 min
Views5.9K

Введение

Мы знаем что наш код выполняется сверху вниз, каждая следующая операция исполнится только после текущей - это называется синхронное программирование. Но довольно часто нам нужно выполнять операции "потом", чуть позже, когда системе будет удобнее. Как же нам быть в этой ситуации ? Тут-то нам на помощь и приходит асинхронное программирование.

? Асинхронное программирование — концепция программирования, которая заключается в том, что результат выполнения функции доступен не сразу, а через некоторое время в виде некоторого асинхронного (нарушающего обычный порядок выполнения) вызова.

Dart, как и, наверное, почти любой другой язык, предоставляет нам возможности не только для синхронного программирования, но и для асинхронного, благодаря таким инструментам как Future и Stream.

Future

Класс Future - наш помощник в создании асинхронных операций.

У Future есть 3 состояния:

  • Uncompleted - незавершенное, операция ещё не запущена или в процессе выполнения

  • Completed with result - операция завершена успешно

  • Completed with error - операция завершена с ошибкой

Пример Future:

Future<String> fetchData() {
  // Создаем и возвращаем объект Future
  return Future(() {
    // Возвращаем результат
    return "Hello World";
  });
}

void main() {
  fetchData().then((data) {
    // Делаем что-то с полученными данными
    print('Fetched data: $data');
  }).catchError((error) {
    // Обрабатываем ошибки
    print("Error fetching data: $error");
  });
}

Когда вы создаете объект Future, он находится в состоянии ожидания, и вы можете добавить функцию, которая будет выполнена, когда Future завершится. Эта функция называется "callback" или "обработчик", её следует передать в метод then. Но then можно и не использовать.

Если выполнение Future завершается с ошибкой, то можно использовать метод catchError для обработки исключения, он перехватывает исключения, которые были выброшены в Future. В этом примере catchError использован для обработки ошибки и вывода сообщения в консоль. Если бы мы не использовали catchError, то исключение просто было бы выброшено и программа бы завершилась с ошибкой.

Таким образом, метод catchError является удобным способом для обработки ошибок в Future и позволяет продолжать выполнение программы в случае ошибки.

async / await

async / await - это синтаксический сахар, который позволяет упростить асинхронный код. Вместо использования then мы можем использовать ключевые слова async / await и вызывать нужные нам функции просто сразу после асинхронного кода. Это позволяет писать более легко читаемый и понятный код. Вот как будет выглядеть код, если мы избавимся от прямого использования Future в примере из прошлого блока:

void main() async {
  // Пробуем получить данные
  try {
    final data = await fetchData();
    print('Fetched data: $data');
  } catch (error) {
    // catch вызывается в случае получения ошибки с блока try
    print("Error fetching data: $error");
  }
}

Future<String> fetchData() async {
  // Возвращаем якобы полученные данные
  return "Hello World";
}

Event Loop

Event Loop - это вечный цикл, выполняющий все задачи

Event loop обрабатывает как асинхронные, так и синхронные функции. Синхронные функции блокируют выполнение Event loop, пока не будут завершены, в то время как асинхронные функции добавляют задачи в очередь и позволяют Event loop продолжать обрабатывать другие задачи, пока они не будут завершены.

Есть 2 очереди задач: Event и MicroTask

Очередь MicroTask

Используется для очень коротких действий, которые должны быть выполнены асинхронно, сразу после завершения какой-либо инструкции перед тем, как передать управление обратно Event Loop.

Очередь microtasks имеет приоритет над обычными и опустошается первой при каждой итерации эвент лупа. Очередь microtasks редко используется разработчиками.

Очередь Event

Используется для планирования операций, которые получают результат от:

  • внешних событий, таких как

    • операции ввода/вывода

    • жесты

    • рисование

    • таймеры

    • потоки

    • ...

  • Future

Фактически, каждый раз при срабатывании внешнего события, соответствующий код ставится в очередь Event.

Пример работы Future в Event Loop

Заключение:

Future - чрезвычайна полезная и обязательная вещь для изучения Flutter программистам, понимание этой темы поможет избежать немалого кол-ва ошибок при работе с асинхронщинной.

Данная статья -вводная, если вы хотите узнать подробнее про асинхронность в Dart, то очень советую данное видео: https://www.youtube.com/watch?v=kLoYHnh9XS0.

Спасибо за прочтение, жду отзывы и правки, если таковые имеются.

Источники:

  1. https://www.youtube.com/watch?v=kLoYHnh9XS0

  2. https://tproger.ru/articles/asynchronous-programming/

  3. https://vk.com/@bonch_dev-isolate-and-event-loops-future-asyncawait

  4. https://chat.openai.com

  5. https://youtu.be/f_KdDUWgef8

  6. https://metanit.com/dart/tutorial/7.1.php

  7. https://habr.com/ru/post/497278/

  8. https://yandex.ru/video/preview/5743019436470613120

Tags:
Hubs:
Total votes 5: ↑5 and ↓0+5
Comments3

Articles