[Dart, Flutter] Flutter. Асинхронность (async) <> параллельность (isolate). Совсем
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Вступление
Недавно с удивлением обнаружил, что у коллег нет полной ясности, что такое асинхронность во Flutter. Почему-то у них было представление, что если асинхронная функция правильно написана, то она не блокирует интерфейс. Пролистав, пару статей не нашел простого, полного и ясного объяснения всей этой кухни (тут все по принципу — «выберите 2 из 3-х»)). В одной статье даже прочитал, что Dart обладает некоей чудесной асинхронностью, которая позволяет отложить выполнения кода, до тех пор, пока поток не будет посвободнее (что на мой взгляд вводит немного в заблуждение).
Для кого статья
Статья рассчитана на тех, кто только начинает знакомиться с Flutter, поэтому попытаюсь на простом примере в этой небольшой заметке показать, что асинхронность это всего лишь возможность выполнения кода не последовательно. Но, если у вас есть «тяжелая» функция (пусть она даже будет трижды асинхронной) она все равно заблокирует вам интерфейс. Конечно, в реальном продакте, вряд ли вы столкнетесь с такими явными проявлениями (на текущий момент процессора достаточно мощные), но понимать все-таки стоит как это работает.
Поехали
И так, возьмем для экспериментов пример из документации к библиотеке flutter_bloc. Немного модифицируем функцию "_mapTimerStartedToState" класса timer_bloc – закомментируем обновление счетчика чтобы не мешал:
Stream<TimerState> _mapTimerStartedToState(TimerStarted start) async* {
yield TimerRunInProgress(start.duration);
_tickerSubscription?.cancel();
// _tickerSubscription = _ticker
// .tick(ticks: start.duration)
// .listen((duration) => add(TimerTicked(duration: duration)));
}
Добавим новую статическую (заранее делаем ее такой – isolate работает только с ними) функцию:
static Future<void> _heavyComput (SendPort sendPort) async {
await Future.delayed(Duration(seconds: 5));
print('=======================');
print('!!!function finished!!!');
print('=======================');
return null;
}
Тут в качестве эмуляции тяжелых вычислений ждем окончания задержки в 5 секунд.
Модифицируем функцию mapEventToState – добавляем в конце асинхронный вызов _heavyComput:
@override
Stream<TimerState> mapEventToState(
TimerEvent event,
) async* {
. . .
_heavyComput(null);
}
Для первого теста все готово – наша задача наблюдать за волшебными волнами.
Запускаем и видим – волны волнуются, интерфейс не блокируется, сообщение об окончании работы функции через 5 секунд выводится.
Вот она чудесная асинхронность – паника была ложной. Хм… А что если Future.delayed(Duration(seconds: 5)) заменить циклом?
static Future<void> _heavyComput(SendPort sendPort) async {
int pause = 1200000000;
for (int i = 0; i < pause; i++) {}
print('=======================');
print('!!!function finished!!!');
print('=======================');
return null;
}
Запускаем и все — «приехали» – волны больше не волнуются.
Думаю, тут особых объяснений не требуется: даже асинхронная тяжелая функция блокирует все. По-умолчанию весь код выполняется в одном потоке. Просто в первом случае никаких вычислений не требовалось, а требовалось просто подождать, а во втором нужны были вычисления.
Ну, и чтобы статья не получилась совсем уж микроскопической — давайте вызовем эту функцию при помощи isolate. Изменим mapEventToState:
@override
Stream<TimerState> mapEventToState(
TimerEvent event,
) async* {
. . .
var _receivePort = ReceivePort();
var _isolate = Isolate.spawn(_heavyComput, _receivePort.sendPort);
}
Запускаем и видим, что интерфейс не блокируется, сообщение о завершении работы функции получаем с заметной задержкой.
На этом все (как работают async и await — есть много статей, думаю, не стоит на этом останавливаться).
Пример можно скачать по ссылке — flutter_timer_async_and_parallels
===========
Источник:
habr.com
===========
Похожие новости:
- [Open source, Программирование, Dart, Flutter] Как создать кастомный плагин для Dart-анализатора
- [Программирование, Java] Шпаргалка по Spring Boot WebClient (перевод)
- [Разработка под iOS, Разработка мобильных приложений, Разработка под Android] Чего ждать от коробочных приложений?
- [IT-стандарты, VueJS, TypeScript] Идеальное Vue приложение на Typescript
- [Программирование, Разработка под Android, Flutter] Flutter ListView и ScrollPhysics: Детальный взгляд (перевод)
- [Разработка под iOS, Разработка мобильных приложений, Разработка под Android, Аналитика мобильных приложений] Как мы просто сократили объем входящего в дата-центр трафика на 70%
- [Программирование, Разработка мобильных приложений, Конференции, Flutter] Анонс вебинара «Почему компании всё чаще выбирают Flutter и что это значит для разработчиков»
- [Информационная безопасность, Анализ и проектирование систем, API, Исследования и прогнозы в IT] OAuth 2.0 -> OAuth 2.1. Что дальше?
- [Программирование, Разработка мобильных приложений, Dart, Flutter] Работа с асинхронностью в Dart
- [Разработка под iOS, Разработка мобильных приложений, Администрирование баз данных, Swift] Быстрый, простой, сложный: как мы выпилили Realm
Теги для поиска: #_dart, #_flutter, #_flutter, #_dart, #_async, #_isolat, #_mobilnaja_razrabotka (мобильная разработка), #_dart, #_flutter
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 16:32
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Вступление Недавно с удивлением обнаружил, что у коллег нет полной ясности, что такое асинхронность во Flutter. Почему-то у них было представление, что если асинхронная функция правильно написана, то она не блокирует интерфейс. Пролистав, пару статей не нашел простого, полного и ясного объяснения всей этой кухни (тут все по принципу — «выберите 2 из 3-х»)). В одной статье даже прочитал, что Dart обладает некоей чудесной асинхронностью, которая позволяет отложить выполнения кода, до тех пор, пока поток не будет посвободнее (что на мой взгляд вводит немного в заблуждение). Для кого статья Статья рассчитана на тех, кто только начинает знакомиться с Flutter, поэтому попытаюсь на простом примере в этой небольшой заметке показать, что асинхронность это всего лишь возможность выполнения кода не последовательно. Но, если у вас есть «тяжелая» функция (пусть она даже будет трижды асинхронной) она все равно заблокирует вам интерфейс. Конечно, в реальном продакте, вряд ли вы столкнетесь с такими явными проявлениями (на текущий момент процессора достаточно мощные), но понимать все-таки стоит как это работает. Поехали И так, возьмем для экспериментов пример из документации к библиотеке flutter_bloc. Немного модифицируем функцию "_mapTimerStartedToState" класса timer_bloc – закомментируем обновление счетчика чтобы не мешал: Stream<TimerState> _mapTimerStartedToState(TimerStarted start) async* {
yield TimerRunInProgress(start.duration); _tickerSubscription?.cancel(); // _tickerSubscription = _ticker // .tick(ticks: start.duration) // .listen((duration) => add(TimerTicked(duration: duration))); } Добавим новую статическую (заранее делаем ее такой – isolate работает только с ними) функцию: static Future<void> _heavyComput (SendPort sendPort) async {
await Future.delayed(Duration(seconds: 5)); print('======================='); print('!!!function finished!!!'); print('======================='); return null; } Тут в качестве эмуляции тяжелых вычислений ждем окончания задержки в 5 секунд. Модифицируем функцию mapEventToState – добавляем в конце асинхронный вызов _heavyComput: @override
Stream<TimerState> mapEventToState( TimerEvent event, ) async* { . . . _heavyComput(null); } Для первого теста все готово – наша задача наблюдать за волшебными волнами. Запускаем и видим – волны волнуются, интерфейс не блокируется, сообщение об окончании работы функции через 5 секунд выводится. Вот она чудесная асинхронность – паника была ложной. Хм… А что если Future.delayed(Duration(seconds: 5)) заменить циклом? static Future<void> _heavyComput(SendPort sendPort) async {
int pause = 1200000000; for (int i = 0; i < pause; i++) {} print('======================='); print('!!!function finished!!!'); print('======================='); return null; } Запускаем и все — «приехали» – волны больше не волнуются. Думаю, тут особых объяснений не требуется: даже асинхронная тяжелая функция блокирует все. По-умолчанию весь код выполняется в одном потоке. Просто в первом случае никаких вычислений не требовалось, а требовалось просто подождать, а во втором нужны были вычисления. Ну, и чтобы статья не получилась совсем уж микроскопической — давайте вызовем эту функцию при помощи isolate. Изменим mapEventToState: @override
Stream<TimerState> mapEventToState( TimerEvent event, ) async* { . . . var _receivePort = ReceivePort(); var _isolate = Isolate.spawn(_heavyComput, _receivePort.sendPort); } Запускаем и видим, что интерфейс не блокируется, сообщение о завершении работы функции получаем с заметной задержкой. На этом все (как работают async и await — есть много статей, думаю, не стоит на этом останавливаться). Пример можно скачать по ссылке — flutter_timer_async_and_parallels =========== Источник: habr.com =========== Похожие новости:
|
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 16:32
Часовой пояс: UTC + 5