Для кого эта статья?

Данная статья будет полезна тем, кто знаком с основами Dart и Flutter, и решил начать изучение асинхронности в Dart. Мы планируем серию статей, которая поможет безболезненно погрузиться в эту тему. Это первая часть серии.

Зачем нам многопоточность в однопоточном Dart?

Dart создали как аналог JS однопоточным,так как Вебе все однопоточное, позже же Dart начали использовать как язык для фреймворка Flutter.

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

Как быстро сделать бутерброд, пока загружается страница

Это история про асинхронность - что такое асинхронность?

Синхронный порядок - выполнения кода сверху вниз. Пока чайник не закипит, ты не попьешь чай.

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

Тот самый бутерброд
Тот самый бутерброд

Но в дарт асинхронные операции в чистом виде не работают так, ниже вы узнаете почему, но сейчас объясню по другому. Асинхронность в dart это как написание диплома, сказали что надо сделать, но начнешь ты это делать только потом когда-нибудь, когда освободишься(или не прижмет await).

Все вопросы которые у тебя возникают во время прочтения задавай в комментариях, я же в свое время предполагаю что эта за вопросы и буду их объяснять в этой или следующих статьях :)

Разберем на примере человека механизм выполнения кода в dart

Event Loop (цикл событий) - это обычный человек. Он делает все по очереди по кругу, все, что нужно. У него как у всех нас есть какие-то повседневные дела(синхронные операции), которые он выполняет сразу, а есть также какие-то срочные важные дела(MicroTask), а есть важные или срочные дела(Event).

Event Loop (Цикл событий) - это механизм, который управляет тем, как выполнение кода происходит в Dart. Он работает в бесконечном цикле, непрерывно проверяя очередь событий и выполняя код, связанный с каждым событием. Когда Dart начинает выполнение, Event Loop сначала выполняет синхронные операции, а затем проверяет очередь событий (MicroTask) и затем выполняет обработчики событий(Event).

Цикл обработки событий EventLoop от Dart похож на Javascript тем, что в нем есть две очереди FIFO: «Очередь событий и очередь микрозадач».

MicroTask

MicroTask - это важные срочные дела, которые мы делаем не каждый день. Например, пойти к стоматологу. Обычно такие дела быстрые, иначе они могут отразиться на нашей продуктивности, но без них мы не можем (быстрый ответ на действия пользователя в приложении).

Таким образом, MicroTask позволяет обрабатывать задачи в приоритетном порядке, что может быть полезно, например, для обновления пользовательского интерфейса.

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

Event

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

Очередь событий (Event queue) содержит все внешние события: ввод-вывод, события мыши, события рисования, таймеры, сообщения между изолятами Dart и так далее. Практически вся асинхронность находится в Event, именно с ней разработчики работают больше всего.

Пример однопоточности в Dart

Допустим, я являюсь человеком. Я хожу на работу, пылесошу, выношу мусор, готовлю, хожу в магазин - все эти действия я заношу в Event Loop. После окончания бытовых дел мне пора ехать на работу.

Когда я еду на работу, у меня ломается машина и она больше не может ехать. Следовательно, создается MicroTask "Починить машину". Но для того, чтобы ее починить, мне нужно позвонить в автосервис, чтобы они приехали и забрали машину, а затем починили. Это пример того, как работают зависящие MicroTask от другой MicroTask. После того, как я закончил важные и срочные дела, я могу посмотреть смс в телефоне и ответить на него(Event).

Алгоритм выполнения
Алгоритм выполнения

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

Утро

Из этого примера мы видим, что вначале выполняются события Event Loop, затем MicroTask, и затем Event.

void main() {

// Добавляется в Event Loop

print('Встать с кровати');

print('Потянуться');

print('Поставить чайник');

// Добавляется в Event

// Чайник должен закипеть, как только он закипит и мы услышим свист.

Future(() => print('Чайник нагрелся'))

.then((value) => print('Услышать свист чайника'));

// Добавляется в MicroTask

Future.microtask(() => print('Покормить кота'));

}

Мы узнали основные механизмы обеспечения асинхронности в dart. Как мы видим появились какие-то новые для нас слова Future, .then, .micro tasks. Разберем их в следующей статье. Мы советуем дочитать весь цикл статей и затем говорить о его целостности. Расскажите в комментариях как вам статья, примеры?

Комментарии (2)


  1. Pastoral
    12.08.2023 13:59
    +2

     Расскажите в комментариях как вам статья, примеры?

    Статья убогая, ничего не прояснила, полна грязи. Под картинкой - алгоритм выполнения чего? А должно было быть очевидно с первого взгляда - на main история не заканчивается.

    Ага, MicroTasks не пустой - ладно, run microtasks значит. Но если множественное число, то сколько? Если run все что есть - какой смысл возврата к проверке пустой ли? Если не все, то сколько?

    И самое интересное в этой схеме - если чудо никак графически не выделенного Event Loop разворачивается после main, то как приложение типа Flutter может ждать событий? Такое на следующие статьи оставлять нельзя.

    И либо пишем про идею параллелизма полно и правильно, либо не пишем вообще, полагая её известной. А объяснения на примере человека - отписка.

    Цикл обработки событий EventLoop от Dart похож на Javascript тем, что в нем есть две очереди FIFO: «Очередь событий и очередь микрозадач».

    А вот после этого - либо пишем ещё столько же текста про JavaScript, либо идею паралеллизма уж точно полагаем известной, либо не упоминаем JavaScript вообще.

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

    Ни что происходит, ни почему не разобрались. Причины, сдаётся мне, тому изобильны, и необходимость того для рассмотреть и Event Loop, и Isolates, и насколько Dart может работать интерпретатором одновременно - среди них не последняя.


    1. programiss Автор
      12.08.2023 13:59

      Спасибо, что написали своем мнение обязательно учтем!) Да действительно забыли написать о том, как dart реализовывает многопоточность.