Андрей Кейда
Андрей Кейда
(обновлено )
За все время: 240 просмотров, 63 посетителя.
За последние 30 дней: 1 просмотр, 1 посетитель.

Основы Dart 2.x (DartVM, Isolates, Streams)

Dart virtual machine

VM (понятие виртуальной машины) - это программа, которая действует как компьютер. Она имитирует процессор с несколькими другими аппаратными компонентами, позволяя выполнять арифметику, считывать из памяти и записывать туда, а также взаимодействовать с устройствами ввода-вывода, словно настоящий физический компьютер.
Сколько аппаратного обеспечения имитирует конкретная VM — зависит от её предназначения. Некоторые VM воспроизводят поведение одного конкретного компьютера. создаёт одну стандартную архитектуру CPU, которая симулируется на различных аппаратных устройствах. В первую очередь это делается для облегчения разработки ПО. Представьте, что вы хотите создать программу, работающую на нескольких компьютерных архитектурах. Виртуальная машина даёт стандартную платформу, которая обеспечивает переносимость. Не нужно переписывать программу для разных платформ или ОС. Достаточно сделать только VM которая будет интерпретировать вашу программу для каждой платформы. После этого любую программу можно написать лишь единожды.
Dart_VM - состоит из набора компонентов для выполнения Dart кода. в частности, она включает в себя следующие компоненты:
- Среда исполнения
- "Сборщик мусора"
- Основные библиотеки и нативные методы
- Система отладка
- Профилировщик
- Симулятор ARM архитектуры
- Возможность использовать горячую перезагрузку (с применением JIT-компиляции) и компиляцию AOT (процесс компиляции выполняется полностью перед выполнением программы).
Разработчики Dart VM утверждают что VM которая используется для Dart это скорее среда выполнения (аналогию можно провести с CLR в .NET), нежели виртуальная машина, так как её работа и функциональность далеко за гранью обычно виртуальной машины.


Важно понимать:
Перед запуском вашей Dart программы в ОС, изначально запускается виртуальная машина Dart (или среда выполнения) и внутри её выполняется ваша программа.


Isotales (изоляты)



Использовать изоляты - это единственный способ работы с многопоточностью в Dart.
Приведем пример:
Изоляты могут общаться между собой с помощью сообщений, каждый изолят предоставляет порт, который используется чтобы передать сообщение, этот порт называется SendPort.

// Создаем порт нового Изолята для отправки сообщения

SendPort newIsolateSendPort;

// Экземпляр нового изолята

Isolate newIsolate;


// Метод, который запускает новый изолят

void callerCreateIsolate() async {


// Временный порт приема сообщений

// Новый порт Изолятов

ReceivePort receivePort = ReceivePort();


// Экземпляр нового Изолята

newIsolate = await Isolate.spawn(

callbackFunction,

receivePort.sendPort,

);


// Извлечение нового порта для общения

newIsolateSendPort = await receivePort.first;

}


// Точка входа нового Изолята

static void callbackFunction(SendPort callerSendPort){


// Инстанцирует отправляющий порт для приема сообщения

ReceivePort newIsolateReceivePort = ReceivePort();



// Предоставляет ссылку на SandPort новых Изолятов

callerSendPort.send(newIsolateReceivePort.sendPort);


// Дальнейшее использование Изолятов ...


}


Что бы ознакомится с Изолятами более подробно рекомендую обратится к документации:
DOC-DART_ISOLATES

Streams (потоки)

Stream в Dart - это последовательность асинхронных событий. Stream сообщает вам, что есть событие и когда оно будет готово.

Существует два типа потоков:
- Потоки-подписки (single subscription)
- Широковещательные (broadcast).

Потоки-подписки - это тип потока который содержит последовательность событий, которые являются частями большего целого. События должны быть доставлены в правильном порядке без пропуска любого из них. Это тип потока, который вы получаете при чтении файла или получении веб-запроса. Такой поток можно слушать только один раз. Прослушивание позже, может означать пропуск начальных событий, и тогда остальная часть потока не имеет смысла. Когда вы начнете слушать, данные будут извлечены и предоставлены кусками.
Широковещательные потоки - тип потока предназначен для отдельных сообщений, которые могут обрабатываться по одному. Вы можете начать слушать такой поток в любое время, и вы получите события, произошедшие во время прослушивания. Поток могут слушать несколько слушателей. Вы можете снова начать слушать события потока после отмены предыдущей подписки.
Немного примеров:

// Для создания потока используем StreamController

var controller = new StreamController<String>();

// Отправляем первый элемент в поток

controller.add("Item1");


var controller = new StreamController<String>();


// Прослушиваем поток

controller.stream.listen((item) => print(item));


controller.add("Item1");

controller.add("Item2");

controller.add("Item3");


var controller = new StreamController<String>();

StreamSubscription subscription = controller.stream.listen((item) => print(item));


controller.add("Item1");

controller.add("Item2");

controller.add("Item3");


// Это сделано для того, чтобы среда тестирования не убила этот процесс

// до того, как все объекты из Stream были обработаны

await Future.delayed(Duration(milliseconds: 500));


subscription.cancel;


Знания о Streams очень необходимы при работе с Rx, сокращенно от Reactive Extensions (реактивные расширения), — это потоки "на стероидах". Это концепция, очень похожая на Streams, которая была изобретена для .Net framework командой Microsoft. Так как .Net уже имел тип Stream, который используется для файлового ввода-вывода, они назвали Rx-потоки Observables и создали множество функций для манипулирования данными, проходящими через них. Dart имеет Streams, встроенные в его языковую спецификацию, которые уже предлагают большую часть этой функциональности, но не все. Вот почему был разработан пакет RxDart; он основан на Dart Streams, но расширяет их функциональность.

Подборка заметок