В отличие от Android, который является многопоточным, то есть любая задача может быть назначена разным потокам и может выполняться одновременно, Dart / Flutter является однопоточным, что просто означает, что у нас не может быть двух или более потоков, работающих параллельно. Только один поток забирает события из очереди событий и обрабатывает их.

В этой статье мы познакомимся с концепцией асинхронного программирования, которую многим разработчикам сложно понять в первую очередь, и с тем, как dart использует такие API, как Future, async и await, чтобы реализовать это. Но сначала давайте разберемся, что такое синхронное программирование.

Синхронное программирование

Синхронное программирование - это форма программирования, при которой программа выполняется построчно. Когда функция вызывается, выполнение программы будет ждать, пока функция не вернется.

Давайте разберемся в этом на примере

Предположим, есть 3 метода, которые нужно выполнить

method1 ()

method2 ()

method3 ()

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

В приведенном выше примере сначала выполняется method1 (), а затем method2 () и method3 ().

Теперь предположим, что method2 () выполняет некоторую операцию, например получение данных из огромной базы данных или загрузку изображения. Тогда выполнение таких долгих и тяжелых задач может занять несколько секунд. И до тех пор, пока method2 () не выполнит, никакая другая последующая функция в Function Stack не может быть выполнена. Поскольку с синхронным программированием мы не получаем такой гибкости.

Это может заморозить пользовательский интерфейс нашего приложения и привести к сбою приложения и плохому UX ‘(

Длительная операция - это термин, используемый для обозначения задач, которые не могут выполняться мгновенно и могут занять несколько секунд. Например, сетевые операции, обработка изображений, загрузка файлов и т. Д.

Теперь вам может быть интересно, как решить такую ​​проблему и повысить производительность нашего приложения, поскольку dart не поддерживает концепцию нескольких потоков.

Асинхронное программирование

Асинхронное программирование - это форма параллельного программирования, которая позволяет выполнять события параллельно с одним потоком, который контролирует все эти события.

Для реализации этого в Dart используются такие API-интерфейсы, как Future, async и await. Давайте возьмем еще один пример и тщательно разберемся с этой концепцией.

Снова предположим, что есть 3 метода, которые необходимо выполнить.

method1 () - ›Обычная функция

method2 (callback) - ›ресурсоемкая функция

method3 () - ›Обычная функция

Здесь method2 () - это long-heavy функция с обратным вызовом, что означает, что компилятор не остановится на этом и не выполнит последующие методы до тех пор, пока method2 () возвращает некоторые данные или ошибку.

Теперь вы можете спросить, чем method2 () отличается от других методов и чем он отличается от других.

Да правильно. Как?

Здесь method2 () вернет объект класса Future, который аналогичен Promises, доступному в других языках программирования. Проще говоря, Future - это обещание компилятору, что он даст ему что-то взамен, как только у него будет что-то дать.

Это немного переборщило? Не стоит беспокоиться ' )

Предположим, method2 () возвращает некоторые данные из огромной базы данных. Выполнение этой задачи может занять несколько секунд. Здесь мы будем использовать Future, который сообщает компилятору «Не ждите, пока я выполню и верну что-то, вместо этого идите и выполните некоторые другие функции. Я сообщу вам данные / ошибку, когда они у меня будут ».

По определению объект Future имеет три состояния:

  1. Незавершенное - когда объект Future еще не завершен.
  2. Завершено с данными - когда объект Future завершен и получит свои данные.
  3. Завершено с ошибкой - когда объект Future завершен, но выдается ошибка.

Теперь разберитесь с концепцией с помощью некоторого фрагмента кода.

Здесь, поскольку для выполнения метода method2 () требуется 5 секунд. Тем временем выполняются методы method1 () и method3 (). Здесь мы использовали самую простую форму Future.delayed (), которая ничего не возвращает.

Теперь рассмотрим еще один сценарий, в котором наш method2 () возвращает некоторое значение Future, а мы возвращаем объект Future типа String.

Обратите внимание на неожиданный результат. Это связано с тем, что на момент запуска нашей программы у нас не было значения resultantData. У нас только что был действующий объект Future, но мы получаем значение resultantData по истечении указанного времени задержки, что означает, что когда программа завершилась, только мы получили бы значение resultantData.

Как теперь получить ожидаемый результат?

Чтобы получить значение переменной content, нам нужно использовать термины await и async.

Как только компилятор обнаруживает ключевое слово await, он будет выполнять код дальше только тогда, когда получит значение / ошибку, и теперь, поскольку мы получаем допустимое значение для содержимого, мы поменяю его тип на исходный, то есть String.

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

Надеюсь, теперь эта статья немного поможет вам понять сложную концепцию асинхронного программирования самым простым способом.

Если вы хотите узнать больше о Futures в флаттере. Перейдите к этому удивительному плейлисту от Google

До тех пор. Удачного кодирования ‘)