SlideShare ist ein Scribd-Unternehmen logo
1 von 40
Downloaden Sie, um offline zu lesen
Асинхронное
программирование
Методы реализации основных
асинхронных задач в различных
платформах
и микрофреймворк для ActionScript
-

Часть I

Основные задачи асинхронного программирования
ActionScript: Event, EventDispatcher, ENTER_FRAME
JavaScript: onclick etc., EventDispatcher
jQuery: on, trigger, $.Deferred, $.Callbacks, $.when
Python: tornadoweb, IOLoop
-

Основные задачи

Создание интерактива для GUI
Клиент-серверное взаимодействие
Загрузка ассетов
Анимация
Взаимодействие между различными частями приложения при
помощи жестких однонаправленных связей (REQ-REP).
- Взаимодействие между различными частями приложения при
помощи слабых связей (PUB-SUB).
- Фоновые процессы
ActionScript 3
Event, EventDispatcher

- Отлично подходит для реализации интерактива в GUI.
Собственно, для этого и создавался.
- Клиент-серверные приложения, загрузка ассетов - не очень
удобно, нативный Loader мало кто использует. Чаще всего
BulkLoader, или велосипеды.
- Анимация, фоновые процессы - самый распространненный
подход - через ENTER_FRAME. Не очень хорошо подходит ни для
того, ни для другого. Для фоновых процессов можно
использовать LocalConnection, который работает на тех же
ивентах, или Worker. С анимацией все намного печальнее.
- Реализация однонаправленных жестких связей - очень плохо.
Нельзя явно описать в интерфейсе или классе-прототипе.
Оверхед.
- Слабые связи при помощи Event - нарушение инкапсуляции из
коробки.
Проблемы реализации.

- В нативном AS3 Event используется везде, хотя проектировался
главным образом для GUI. Всвязи с чем содержит много
избыточного функционала (target, currentTarget, bubbling,
capture).
- Проблемы с клонированием в кастомных ивентах GUI. Бажная
реализация самого процесса клонирования.
- Жесткое требование субкласса для
EventDispatcher.dispatchEvent()
- Использование "кнопочного" программирования флешерами
для любой задачи.
JavaScript, jQuery, Backbone
JavaScript. Event.

- Работа с ивентами реализованна практически также, как в
ActionScript. Только есть пережитки прошлого.
- Используется программистами в основном для интерактива и
для загрузки контента. Или я просто не знаю, поэтому сплю
спокойно.
- Нет ENTER_FRAME - для анимации и подобных задач чаще всего
используется setInterval. И это более правильно.
- В javascript гораздо более простая и удобная работа с
функциями: binding, нет глюков с анонимками.
elementOne.addEventListener('click', doSomething, false);
elementTwo.addEventListener('click', doSomething, false);
elementDyno.onclick = doSomething;
function doSomething () {
this.style.backgroundColor = '#cc0000';
}
jQuery.Event

- Расширение нативного функционала.
- Методы on, one - намного более удобный способ
регистрировать хендлеры, чем addEventListener.
- Метод trigger позволяет передавать в хендлер дополнительные
аргументы.
- Любой инстанс jQuery имеет в своем прототипе этот
функционал. Мне это не нравится.
function greet (event, silent) {
if (!silent) {
alert("Hello " + event.data.name);
}
}
$("button").on("click", {name: "Karl"}, greet);
$("button").on("click", ".addy", {name: "Addy"}, greet);
$("button").trigger("click", true); // nothing happens...
Backbone.Events

- Чистая, минималистическая реализация, без использования
нативных JS ивентов.
- Реализован как миксин. То есть может расширять любой объект
или его прототип.
- Метод on позволяет подписаться на "иерархические" ивенты, а
также на несколько ивентов сразу.
- listenTo и stopListening позволяют держать все хендлеры в
текущем объекте, в том числе хендлеры для внешних объектов
и потом быстро их чистить.
- trigger может посылать несколько ивентов сразу. Как и в jQuery
есть возможность передавать аргументы в хендлер.
var emitter = {
name: 'emitter',
handler: function (msg) {
console.log(this.name + ' received: ' + msg);
}
};
_.extend(emitter, Backbone.Events);
emitter.on("alert", function (msg) {
console.log("message: " + msg);
});
emitter.trigger("alert", "an event");
emitter.trigger("alert:foo", "namespaced event");
var external = _.extend({}, Backbone.Events);
emitter.listenTo(external, 'changed removed', emitter.handler);
external.trigger('changed', 'an event');
emitter.stopListening(external, 'changed');
external.trigger('changed', 'an event');
external.trigger('removed', 'bye!');

http://jsfiddle.net/457Yh/
jQuery.Callbacks

Хороший пример реализации однонаправленной жесткой связи
между частями приложения.
var foo = function (value) {
console.log("foo:" + value);
};
var callbacks = $.Callbacks();
callbacks.add(foo);
callbacks.fire("hello");
callbacks.fire("world");
var bar = function( value ){
console.log( "bar:" + value );
};
callbacks.add(bar);
callbacks.fire("hello again");

http://jsfiddle.net/DZNHU/
jQuery.Deferred, jQuery.when.

Класс для реализации однонаправленных жестких связей между
приложением и асинхронным процессом. Описывает основные
состояния процесса, и дает возможность приложению
регистрировать колбеки для каждого из состояний. Позволяет
создавать сложные процессы, за счет чейнинга. В jQuery
предлагается использовать для реализации клиент-серверных
взаимодействий - все ajax запросы возвращают Deferred. Можно
использовать для реализации любых "процессов".
var deferred = $.Deferred();
function foo (msg) {
console.log('foo: ' + msg);
}
function bar (msg) {
console.log('bar: ' + msg);
}
deferred
.done([foo, bar], foo)
.fail(foo);
$('button[name="resolve"]').click(function () {
deferred.resolve('Ok...');
return false;
});
$('button[name="reject"]').click(function () {
deferred.reject('Not ok...');
return false;
});

http://jsfiddle.net/sWvY6/
var checkRequest = function (a1, a2) {
var data = a1[0] + a2[0];
if (/Whip It/.test(data)) {
alert( "We got what we came for!" );
}
}
$.when(ajax("/page1.php"), ajax("/page2.php"))
.done(function (a1, a2) {
// a1 and a2 are arguments resolved for
// the page1 and page2 ajax requests, respectively.
// Each argument is an array
// with the following structure: [data, statusText, jqXHR]
// a1[0] = "Whip", a2[0] = " It"
checkRequest(a1, a2);
}); // Alerts after both pages loaded.
// Nasty hack
$.when(ajax("/page1.php"), [" It"]])
.done(checkRequest); // Alerts when page1 is loaded.
Python, tornadoweb
tornado.concurrent.Future

Инкапсулирует результат асинхронной операции. Ближайший
аналог - $.Callbacks. Отличие - $.Callbacks не имеет никакой
связи с результатом. Привязка ни к объекту, а к процессу и его
результату. Типичный подход для асинхронного
программирования на сервере.

Описание интерфейса

- result() - возвращает результат операции, или выбрасывает
ексепшен.
- exception() - возвращает исключение, как объект.
- add_done_callback(fn) - регистрирует колбек, который
выполнится когда процесс будет завершен. С экземпляром
Future в качестве аргумента.
- done() - возвращает True, если процес завершен.
tornado.ioloop

Асинхронные процессы на сервере как правило связанны с
сокетами. Сокет это объект, похожий на файл, который может
находится в двух состояниях: запись и чтение. I/O Loop
использует функцию ядра OS (epoll в Linux) для того, чтобы
определить когда сокет изменит свое состояние.
Описание интерфейса
(не полное)

- IOLoop.add_handler(fd, handler, events) - регистрирует колбек
handler, который будет выполнен, когда сокет с дескриптором fd
"сгенерирует" один из ивентов в списке events.
- IOLoop.add_callback(callback, *args, **kwargs) - запускает
колбек на следующей итерации IOLoop.
- IOLoop.add_future(future, callback) - запускает колбек на
следующей итерации IOLoop, после того, как future будет
выполнено.
- IOLoop.add_timeout(deadline, callback) - запускает кобек после
наступления deadline.
-

Часть II

Dzyga
DispatcherProxy - работа с ивентами
Promise, Once - работа с колбеками
Task - абстракция для асинхронных процессов
Loop, LoopTask - менеджер колбеков для ENTER_FRAME, реализация
фоновых процессов, инкапсуляция интерактива для GUI.
org.dzyga.events
org.dzyga.event.DispatcherProxy

- Расширение функционала EventDispatcher.
- Облегчение работы с нативными флешовыми EventDispatcher.
- Привязка добавленных к флешовому EventDispatcher
обработчиков событий к конкретному классу с возможностью
быстрого удаления зарегистрированных обработчиков.
- Улучшение производительности, за счет группировки большого
числа обработчиков в очередь. Но в большинстве случаев это
будет работать, конечно, медленнее.
Краткое описание:

Дублирует функционал для добавления обработчиков событий а
также проксирует нативные методы. Реализует IEventDispatcher.
Для обработчиков добавляемых через DispatcherProxy создаются
экземпляры класса EventListener, которые затем сохраняются в
локальную для данного экземпляра коллекцию для обеспечения
лучших возможностей манипуляции обработчиком, чем в
нативном IEventDispatcher.
Позволяет добавлять аргументы в обработчики событий, биндить
их к другим объектам, а также регистрировать обработчики,
которые автоматически удаляются после первого вызова.
Описание интерфейса

Добавление обработчика к проксируемому диспетчеру:
function listen (
eventType:String, callback:Function, once:Boolean = false,
thisArg:* = null, argArray:Array = null):IDispatcherProxy;

Удаление обработчиков с проксируемого диспетчера:
function stopListening (
eventType:String = '',
callback:Function = null):IDispatcherProxy;

Добавление обработчика к любому диспетчеру:

function listenTo (
target:IEventDispatcher, eventType:String,
callback:Function, once:Boolean = false,
thisArg:* = null, argArray:Array = null):IDispatcherProxy;
Удаление обработчиков, зарегистрированных данным прокси с
одного или всех диспетчеров:
function stopListeningTo (
target:IEventDispatcher = null, eventType:String = '',
callback:Function = null):IDispatcherProxy;

Триггер для простых ивентов:

function triggerTo (
target:IEventDispatcher, eventType:String):IDispatcherProxy;

Проверка зарегистрированных обработчиков:
function isListeningTo (
target:IEventDispatcher = null, eventType:String = '',
callback:Function = null):Boolean;
Пример кода с синтаксическим
сахаром
dispatcher(d)
.listen(MouseEvent.CLICK, onClick)
.listen(MouseEvent.CLICK, onAnotherClick)
.listen(MouseEvent.ROLL_OVER, onOver)
.listen(MouseEvent.ROLL_OUT, onOut)
.listen(MouseEvent.MOUSE_OUT, onOut)
// Next callback will be removed after the first run.
.listen(
Event.ADDED_TO_STAGE, initView,
true, null, ['target init']);
dispatcher(d)
.trigger(MouseEvent.CLICK)
.trigger(MouseEvent.ROLL_OVER)
.trigger(Event.ADDED_TO_STAGE)
// Nothing happens there...
.trigger(Event.ADDED_TO_STAGE);
org.dzyga.callbacks
org.dzyga.callbacks.Promise

- Замена и расширение функционала EventDispatcher.
- Более явная реализация обработки асинхронных процессов promise можно объявлять свойством класса и/или интерфейса.
- Реализация жестких однонаправленных связей между частями
приложения: модуль добавляющий колбек в промис имеет
доступ к модулю обработчику, модуль обработчик в обратную
сторону - нет.

Краткое описание

Для добавляемых колбеков создаются инстансы класса Callback,
которые помещаются в сортированный список. При вызове
метода resolve все находящиеся в списке колбеки выполняются.
Аргументы, заданные при добавлении колбека добавляются в
конец списка аргументов, с которыми была вызван метод resolve.
Описание интерфейса

Добавление колбека:

function callbackRegister (
callback:Function, once:Boolean = false, thisArg:* = null,
argsArray:Array = null):IPromise;

Удаление колбека:

function callbackRemove (callback:Function = null):IPromise;

Запуск колбеков (выполнение обещания):
function resolve (... args):IPromise;
private function firstCallback (inc:int = 1):void {
_firstCounter += inc;
}
private function secondCallback (inc:int = 1):void {
_secondCounter += inc;
}
[Test]
public function testCallbackRegisterUniq ():void {
var promise:Promise = new Promise();
promise
.callbackRegister(firstCallback, false, null, [2])
.callbackRegister(firstCallback)
.callbackRegister(secondCallback)
.resolve();
// 3, if first callback added twice...
assertEquals(2, _firstCounter);
assertEquals(1, _secondCounter);
promise.clear();
}
org.dzyga.callbacks.Once

Простейший субкласс Promise. Если Once был хоть один раз
зарезолвлен, то все колбеки, добавляемые в будующем,
запускаются сразу же после добавления. Как и Promise может быть
зарезолвлен сколько угодно раз. Предусмотрена возможность
повторного использования, при помощи метода reset().
org.dzyga.callbacks.Task

- Реализация асинхронных процессов
- Инкапсуляция переменных и методов связанных с процессом.
- Отделение функционала процесса от объектов, учавствующих в
процессе. В теории, может вести к большим возможностям
повторного использования кода.
- Организация жестких однонаправленных связей между
модулями.
Краткое описание

Cодержит промисы, которые резолвятся на разных стадиях
процесса, и куда, внешние модули могут добавлять колбеки:
-

started - резолвится при запуске асинхронного процесса.
done - резолвится при успешном завершении процесса.
failed - резолвится при неправильном завершении процесса.
finished - резолвится при любом завершении процесса, сразу
после done или failed.
- progress - резолвится на промежуточных стадиях процесса.
Кроме промисов содержит еще поле state, т.е. Task является
стейт-машиной.
Описание интерфейса

Запуск процесса, резолв промиса started с переданными
аргументами:
function start (... args):ITask;

Переключение состояний процесса и резолв соответствующих
промисов:
function notify (... args):ITask;
function resolve (... args):ITask;
function reject (... args):ITask;

Очистка всех промисов и сброс состояния процесса:
function clear ():ITask;

Возвращает одно из значений: TaskState.STARTED,
TaskState.RESOLVED, TaskState.REJECTED или TaskState.IDLE:
function get state ():String;
org.dzyga.eventloop
-

org.dzyga.eventloop.Loop

Реализация фоновых процессов.
Анимация.
Обработка интерактива (замена MOUSE_MOVE)
Ограничение количества запускаемых каждый фрейм
обработчиков, с целью поддерживать заданный fps.

Краткое описание:

Позволяет запускать колбеки каждый фрейм, в том же фрейме, но
в другом стеке, если есть возможность, или по таймауту.
Поддерживает приоритеты. Если очередь колбеков выполняется
дольше зависящего от fps времени - выполнение колбеков в этом
фрейме прекращается, что позволяет поддерживать нужный фпс,
жертвуя, например временем обработки фоновых процессов.
Описание интерфейса

Добавление колбека, который должен запускаться каждый фрейм:
function frameEnterCall (
callback:Function, priority:uint = 1,
thisArg:* = null, argsArray:Array = null):ILoopCallback;

Добавление колбека, который должен запуститься в ближайшее
возможное время:
function call (
callback:Function, priority:uint = 1,
thisArg:* = null, argsArray:Array = null):ILoopCallback;

Добавление колбека по таймауту:

function delayedCall (
callback:Function, delay:Number = 0, priority:uint = 1,
thisArg:* = null, argsArray:Array = null):ILoopCallback;
org.dzyga.eventlooop.LoopTask

Служит для реализации задач, требующих значительного
времени для выполнения: например - препроцессинг анимации.
Метод run экземпляра класса будет выполнятся при помощи
метода Loop.call каждый фрейм, столько раз, сколько позволяет
время. Можно задавать приоритет выполнения колбека. Это
субкласс Task.

org.dzyga.eventlooop.FrameEnterTask

Служит для реализации процессов, которые отвечают за
обновление экрана (анимация) или за отслеживание
происходящего на экране (мышь, положение движущихся
объектов). Также как LoopTask должен содержать метод run,
который при помощи метода Loop.frameEnterCall будет
запускаться каждый фрейм.
Исходник LoopTask
(оптимизирован для просмотра)

public function get callback ():Function {
if (hasOwnProperty('run')) {
return this['run'];
} else {
return FunctionUtils.identity;
}
}
protected function loopCallbackRegister ():void {
if (!_loopCallback) {
_loopCallback = _loop.call(
runner, priority);
}
}
protected function runner ():void {
if (state == TaskState.STARTED) {
_result = callback.apply(
thisArg, argsArray);
}
if (state == TaskState.STARTED) {
loopCallbackRegister();
}
}
protected function loopCallbackCancel ():void {
if (_loopCallback) {
_loopCallback.cancel();
_loopCallback = null;
}
}

protected function loopCallbackRemove ():void {
if (_loopCallback) {
_loop.callbackRemove(_loopCallback);
_loopCallback = null;
}
}
override public function start (...args):ITask {
loopCallbackRegister();
return super.start.apply(this, args);
}
override public function resolve (...args):ITask {
loopCallbackCancel();
return super.resolve.apply(this, args);
}
override public function reject (...args):ITask {
loopCallbackCancel();
return super.reject.apply(this, args);
}
override public function clear ():ITask {
loopCallbackRemove();
return super.clear();
}
Пример реализации интерактива
function loopCallbackRegister ():void {
if (_trackingActive) {
super.loopCallbackRegister();
}
}
function trackingEnable (e:Event = null):void {
_trackingActive = true;
loopCallbackRegister();
}
function trackingDisable (e:Event = null):void {
_trackingActive = false;
loopCallbackCancel();
}
function get trackingActive ():Boolean {
return _trackingActive;
}
function run ():ICell {
var cell:LevelCell = cellMap.cellGet(
_view.mouseX, _view.mouseY);
if (cell != _cell) {
_cell = cell;
notify(_cell);
}
return _cell;
}

function start (...args):ITask {
_trackingActive = _view.active;
_view
.listen(
LevelView.LEVEL_ACTIVATE_EVENT,
trackingEnable)
.listen(
LevelView.LEVEL_DEACTIVATE_EVENT,
trackingDisable);
return super.start.apply(this, args);
}
function stop ():void {
_view
.stopListening(
LevelView.LEVEL_DEACTIVATE_EVENT,
trackingDisable)
.stopListening(
LevelView.LEVEL_ACTIVATE_EVENT,
trackingEnable);
_trackingActive = false;
}

Weitere ähnliche Inhalte

Was ist angesagt?

View как чистая функция от состояния базы данных - Илья Беда, bro.agency
View как чистая функция от состояния базы данных  - Илья Беда, bro.agencyView как чистая функция от состояния базы данных  - Илья Беда, bro.agency
View как чистая функция от состояния базы данных - Илья Беда, bro.agency
it-people
 
Web internship java script
Web internship   java scriptWeb internship   java script
Web internship java script
Noveo
 
Михаил Давыдов — Транспорт, Ajax
Михаил Давыдов — Транспорт, AjaxМихаил Давыдов — Транспорт, Ajax
Михаил Давыдов — Транспорт, Ajax
Yandex
 

Was ist angesagt? (20)

JS Fest 2018. Лилия Карпенко. Особенности создания IOS / Android Mobile Apps ...
JS Fest 2018. Лилия Карпенко. Особенности создания IOS / Android Mobile Apps ...JS Fest 2018. Лилия Карпенко. Особенности создания IOS / Android Mobile Apps ...
JS Fest 2018. Лилия Карпенко. Особенности создания IOS / Android Mobile Apps ...
 
Windows Azure and node js
Windows Azure and node jsWindows Azure and node js
Windows Azure and node js
 
Коротко о React.js
Коротко о React.jsКоротко о React.js
Коротко о React.js
 
Selenium vs AJAX
Selenium vs AJAXSelenium vs AJAX
Selenium vs AJAX
 
Пользователь точно оценит! Повышение производительности мобильных приложений ...
Пользователь точно оценит! Повышение производительности мобильных приложений ...Пользователь точно оценит! Повышение производительности мобильных приложений ...
Пользователь точно оценит! Повышение производительности мобильных приложений ...
 
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
 
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)Многопоточность, работа с сетью (Lecture 12 – multithreading, network)
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)
 
Киллер-фича языка C# — конструкция async/await
Киллер-фича языка C# — конструкция async/awaitКиллер-фича языка C# — конструкция async/await
Киллер-фича языка C# — конструкция async/await
 
Angular 2: Всех переиграл
Angular 2: Всех переигралAngular 2: Всех переиграл
Angular 2: Всех переиграл
 
"VUE.JS как реакт с человеческим лицом" Дулецкий Вольдэмар, Evrone
"VUE.JS как реакт с человеческим лицом" Дулецкий Вольдэмар, Evrone"VUE.JS как реакт с человеческим лицом" Дулецкий Вольдэмар, Evrone
"VUE.JS как реакт с человеческим лицом" Дулецкий Вольдэмар, Evrone
 
HTML 5: будущее уже сегодня, Сергей Байдачный, Microsoft Ukraine
HTML 5: будущее уже сегодня, Сергей Байдачный, Microsoft UkraineHTML 5: будущее уже сегодня, Сергей Байдачный, Microsoft Ukraine
HTML 5: будущее уже сегодня, Сергей Байдачный, Microsoft Ukraine
 
Транзакционный фреймворк для сингловых игр и игр с асинхронным мультиплеером ...
Транзакционный фреймворк для сингловых игр и игр с асинхронным мультиплеером ...Транзакционный фреймворк для сингловых игр и игр с асинхронным мультиплеером ...
Транзакционный фреймворк для сингловых игр и игр с асинхронным мультиплеером ...
 
Где кончается react native? / Павел Кондратенко (Rambler&Co)
Где кончается react native? / Павел Кондратенко (Rambler&Co)Где кончается react native? / Павел Кондратенко (Rambler&Co)
Где кончается react native? / Павел Кондратенко (Rambler&Co)
 
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))
 
JavaScript Базовый. Занятие 07.
JavaScript Базовый. Занятие 07.JavaScript Базовый. Занятие 07.
JavaScript Базовый. Занятие 07.
 
JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.
 
View как чистая функция от состояния базы данных - Илья Беда, bro.agency
View как чистая функция от состояния базы данных  - Илья Беда, bro.agencyView как чистая функция от состояния базы данных  - Илья Беда, bro.agency
View как чистая функция от состояния базы данных - Илья Беда, bro.agency
 
Web internship java script
Web internship   java scriptWeb internship   java script
Web internship java script
 
Михаил Давыдов — Транспорт, Ajax
Михаил Давыдов — Транспорт, AjaxМихаил Давыдов — Транспорт, Ajax
Михаил Давыдов — Транспорт, Ajax
 
Зачем нужен EmberJS, если мне хвататет jQuery
Зачем нужен EmberJS, если мне хвататет jQueryЗачем нужен EmberJS, если мне хвататет jQuery
Зачем нужен EmberJS, если мне хвататет jQuery
 

Andere mochten auch

Событийная модель Action Script 3.0
Событийная модель Action Script 3.0Событийная модель Action Script 3.0
Событийная модель Action Script 3.0
Eldar Prilutskyi
 
автоматизированная сборка Flash приложений (as2, as3). андрей жданов. зал 4
автоматизированная сборка Flash приложений (as2, as3). андрей жданов. зал 4автоматизированная сборка Flash приложений (as2, as3). андрей жданов. зал 4
автоматизированная сборка Flash приложений (as2, as3). андрей жданов. зал 4
rit2011
 
MongoDB первые впечатления
MongoDB первые впечатленияMongoDB первые впечатления
MongoDB первые впечатления
fudz1k
 

Andere mochten auch (9)

Событийная модель Action Script 3.0
Событийная модель Action Script 3.0Событийная модель Action Script 3.0
Событийная модель Action Script 3.0
 
доклад
докладдоклад
доклад
 
"Как написать компилятор за 15 минут", Андрей Гершун, MoscowJS 24
"Как написать компилятор за 15 минут", Андрей Гершун, MoscowJS 24"Как написать компилятор за 15 минут", Андрей Гершун, MoscowJS 24
"Как написать компилятор за 15 минут", Андрей Гершун, MoscowJS 24
 
автоматизированная сборка Flash приложений (as2, as3). андрей жданов. зал 4
автоматизированная сборка Flash приложений (as2, as3). андрей жданов. зал 4автоматизированная сборка Flash приложений (as2, as3). андрей жданов. зал 4
автоматизированная сборка Flash приложений (as2, as3). андрей жданов. зал 4
 
Attacking MongoDB
Attacking MongoDBAttacking MongoDB
Attacking MongoDB
 
Разница между кодированием и программированием - Виталий Хить
Разница между кодированием и программированием - Виталий ХитьРазница между кодированием и программированием - Виталий Хить
Разница между кодированием и программированием - Виталий Хить
 
Преимущества NoSQL баз данных на примере MongoDB
Преимущества NoSQL баз данных на примере MongoDBПреимущества NoSQL баз данных на примере MongoDB
Преимущества NoSQL баз данных на примере MongoDB
 
MongoDB basics in Russian
MongoDB basics in RussianMongoDB basics in Russian
MongoDB basics in Russian
 
MongoDB первые впечатления
MongoDB первые впечатленияMongoDB первые впечатления
MongoDB первые впечатления
 

Ähnlich wie FPUG Dzyga presentation

Mobile automation uamobile
Mobile automation uamobileMobile automation uamobile
Mobile automation uamobile
UA Mobile
 
Школа-Студия разработки приложений для iOS. 5 лекция. Разное
Школа-Студия разработки приложений для iOS. 5 лекция. РазноеШкола-Студия разработки приложений для iOS. 5 лекция. Разное
Школа-Студия разработки приложений для iOS. 5 лекция. Разное
Глеб Тарасов
 
Take more from Jquery
Take more from JqueryTake more from Jquery
Take more from Jquery
Magento Dev
 
I tmozg js_school
I tmozg js_schoolI tmozg js_school
I tmozg js_school
ITmozg
 

Ähnlich wie FPUG Dzyga presentation (20)

Асинхронный JavaScript
Асинхронный JavaScriptАсинхронный JavaScript
Асинхронный JavaScript
 
iOS and Android Mobile Test Automation
iOS and Android Mobile Test AutomationiOS and Android Mobile Test Automation
iOS and Android Mobile Test Automation
 
Mobile automation uamobile
Mobile automation uamobileMobile automation uamobile
Mobile automation uamobile
 
Зачем нужен JavaScript в iOS-приложениях. Евгений Дымов
 Зачем нужен JavaScript в iOS-приложениях. Евгений Дымов Зачем нужен JavaScript в iOS-приложениях. Евгений Дымов
Зачем нужен JavaScript в iOS-приложениях. Евгений Дымов
 
Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1
 
Mike ponomarenko java17-fork-v1.2
Mike ponomarenko java17-fork-v1.2Mike ponomarenko java17-fork-v1.2
Mike ponomarenko java17-fork-v1.2
 
Автоматизация UI тестирования под Windows и Windows Phone
Автоматизация UI тестирования под Windows и Windows PhoneАвтоматизация UI тестирования под Windows и Windows Phone
Автоматизация UI тестирования под Windows и Windows Phone
 
Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1
 
Школа-Студия разработки приложений для iOS. 5 лекция. Разное
Школа-Студия разработки приложений для iOS. 5 лекция. РазноеШкола-Студия разработки приложений для iOS. 5 лекция. Разное
Школа-Студия разработки приложений для iOS. 5 лекция. Разное
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй это
 
Опыт разработки эффективного SPA
Опыт разработки эффективного SPAОпыт разработки эффективного SPA
Опыт разработки эффективного SPA
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profiler
 
Node.js введение в технологию, КПИ #ITmeetingKPI
Node.js введение в технологию, КПИ  #ITmeetingKPINode.js введение в технологию, КПИ  #ITmeetingKPI
Node.js введение в технологию, КПИ #ITmeetingKPI
 
automation is iOS development
automation is iOS developmentautomation is iOS development
automation is iOS development
 
Take more from Jquery
Take more from JqueryTake more from Jquery
Take more from Jquery
 
Тестирование отклика Web-интерфейса с JMeter и Selenium
Тестирование отклика Web-интерфейса с JMeter и SeleniumТестирование отклика Web-интерфейса с JMeter и Selenium
Тестирование отклика Web-интерфейса с JMeter и Selenium
 
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...
 
Erlang tasty & useful stuff
Erlang tasty & useful stuffErlang tasty & useful stuff
Erlang tasty & useful stuff
 
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScriptСтажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
 
I tmozg js_school
I tmozg js_schoolI tmozg js_school
I tmozg js_school
 

Kürzlich hochgeladen

ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
Ирония безопасности
 
Cyberprint. Dark Pink Apt Group [RU].pdf
Cyberprint. Dark Pink Apt Group [RU].pdfCyberprint. Dark Pink Apt Group [RU].pdf
Cyberprint. Dark Pink Apt Group [RU].pdf
Хроники кибер-безопасника
 
CVE. The Fortra's GoAnywhere MFT [RU].pdf
CVE. The Fortra's GoAnywhere MFT [RU].pdfCVE. The Fortra's GoAnywhere MFT [RU].pdf
CVE. The Fortra's GoAnywhere MFT [RU].pdf
Хроники кибер-безопасника
 
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdfСИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
Хроники кибер-безопасника
 
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
Ирония безопасности
 
2023 Q4. The Ransomware report. [RU].pdf
2023 Q4. The Ransomware report. [RU].pdf2023 Q4. The Ransomware report. [RU].pdf
2023 Q4. The Ransomware report. [RU].pdf
Хроники кибер-безопасника
 

Kürzlich hochgeladen (9)

ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
 
Cyberprint. Dark Pink Apt Group [RU].pdf
Cyberprint. Dark Pink Apt Group [RU].pdfCyberprint. Dark Pink Apt Group [RU].pdf
Cyberprint. Dark Pink Apt Group [RU].pdf
 
Malware. DCRAT (DARK CRYSTAL RAT) [RU].pdf
Malware. DCRAT (DARK CRYSTAL RAT) [RU].pdfMalware. DCRAT (DARK CRYSTAL RAT) [RU].pdf
Malware. DCRAT (DARK CRYSTAL RAT) [RU].pdf
 
MS Navigating Incident Response [RU].pdf
MS Navigating Incident Response [RU].pdfMS Navigating Incident Response [RU].pdf
MS Navigating Incident Response [RU].pdf
 
CVE. The Fortra's GoAnywhere MFT [RU].pdf
CVE. The Fortra's GoAnywhere MFT [RU].pdfCVE. The Fortra's GoAnywhere MFT [RU].pdf
CVE. The Fortra's GoAnywhere MFT [RU].pdf
 
Ransomware_Q3 2023. The report [RU].pdf
Ransomware_Q3 2023.  The report [RU].pdfRansomware_Q3 2023.  The report [RU].pdf
Ransomware_Q3 2023. The report [RU].pdf
 
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdfСИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
 
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
 
2023 Q4. The Ransomware report. [RU].pdf
2023 Q4. The Ransomware report. [RU].pdf2023 Q4. The Ransomware report. [RU].pdf
2023 Q4. The Ransomware report. [RU].pdf
 

FPUG Dzyga presentation

  • 1. Асинхронное программирование Методы реализации основных асинхронных задач в различных платформах и микрофреймворк для ActionScript
  • 2. - Часть I Основные задачи асинхронного программирования ActionScript: Event, EventDispatcher, ENTER_FRAME JavaScript: onclick etc., EventDispatcher jQuery: on, trigger, $.Deferred, $.Callbacks, $.when Python: tornadoweb, IOLoop
  • 3. - Основные задачи Создание интерактива для GUI Клиент-серверное взаимодействие Загрузка ассетов Анимация Взаимодействие между различными частями приложения при помощи жестких однонаправленных связей (REQ-REP). - Взаимодействие между различными частями приложения при помощи слабых связей (PUB-SUB). - Фоновые процессы
  • 5. Event, EventDispatcher - Отлично подходит для реализации интерактива в GUI. Собственно, для этого и создавался. - Клиент-серверные приложения, загрузка ассетов - не очень удобно, нативный Loader мало кто использует. Чаще всего BulkLoader, или велосипеды. - Анимация, фоновые процессы - самый распространненный подход - через ENTER_FRAME. Не очень хорошо подходит ни для того, ни для другого. Для фоновых процессов можно использовать LocalConnection, который работает на тех же ивентах, или Worker. С анимацией все намного печальнее. - Реализация однонаправленных жестких связей - очень плохо. Нельзя явно описать в интерфейсе или классе-прототипе. Оверхед. - Слабые связи при помощи Event - нарушение инкапсуляции из коробки.
  • 6. Проблемы реализации. - В нативном AS3 Event используется везде, хотя проектировался главным образом для GUI. Всвязи с чем содержит много избыточного функционала (target, currentTarget, bubbling, capture). - Проблемы с клонированием в кастомных ивентах GUI. Бажная реализация самого процесса клонирования. - Жесткое требование субкласса для EventDispatcher.dispatchEvent() - Использование "кнопочного" программирования флешерами для любой задачи.
  • 8. JavaScript. Event. - Работа с ивентами реализованна практически также, как в ActionScript. Только есть пережитки прошлого. - Используется программистами в основном для интерактива и для загрузки контента. Или я просто не знаю, поэтому сплю спокойно. - Нет ENTER_FRAME - для анимации и подобных задач чаще всего используется setInterval. И это более правильно. - В javascript гораздо более простая и удобная работа с функциями: binding, нет глюков с анонимками. elementOne.addEventListener('click', doSomething, false); elementTwo.addEventListener('click', doSomething, false); elementDyno.onclick = doSomething; function doSomething () { this.style.backgroundColor = '#cc0000'; }
  • 9. jQuery.Event - Расширение нативного функционала. - Методы on, one - намного более удобный способ регистрировать хендлеры, чем addEventListener. - Метод trigger позволяет передавать в хендлер дополнительные аргументы. - Любой инстанс jQuery имеет в своем прототипе этот функционал. Мне это не нравится. function greet (event, silent) { if (!silent) { alert("Hello " + event.data.name); } } $("button").on("click", {name: "Karl"}, greet); $("button").on("click", ".addy", {name: "Addy"}, greet); $("button").trigger("click", true); // nothing happens...
  • 10. Backbone.Events - Чистая, минималистическая реализация, без использования нативных JS ивентов. - Реализован как миксин. То есть может расширять любой объект или его прототип. - Метод on позволяет подписаться на "иерархические" ивенты, а также на несколько ивентов сразу. - listenTo и stopListening позволяют держать все хендлеры в текущем объекте, в том числе хендлеры для внешних объектов и потом быстро их чистить. - trigger может посылать несколько ивентов сразу. Как и в jQuery есть возможность передавать аргументы в хендлер.
  • 11. var emitter = { name: 'emitter', handler: function (msg) { console.log(this.name + ' received: ' + msg); } }; _.extend(emitter, Backbone.Events); emitter.on("alert", function (msg) { console.log("message: " + msg); }); emitter.trigger("alert", "an event"); emitter.trigger("alert:foo", "namespaced event"); var external = _.extend({}, Backbone.Events); emitter.listenTo(external, 'changed removed', emitter.handler); external.trigger('changed', 'an event'); emitter.stopListening(external, 'changed'); external.trigger('changed', 'an event'); external.trigger('removed', 'bye!'); http://jsfiddle.net/457Yh/
  • 12. jQuery.Callbacks Хороший пример реализации однонаправленной жесткой связи между частями приложения. var foo = function (value) { console.log("foo:" + value); }; var callbacks = $.Callbacks(); callbacks.add(foo); callbacks.fire("hello"); callbacks.fire("world"); var bar = function( value ){ console.log( "bar:" + value ); }; callbacks.add(bar); callbacks.fire("hello again"); http://jsfiddle.net/DZNHU/
  • 13. jQuery.Deferred, jQuery.when. Класс для реализации однонаправленных жестких связей между приложением и асинхронным процессом. Описывает основные состояния процесса, и дает возможность приложению регистрировать колбеки для каждого из состояний. Позволяет создавать сложные процессы, за счет чейнинга. В jQuery предлагается использовать для реализации клиент-серверных взаимодействий - все ajax запросы возвращают Deferred. Можно использовать для реализации любых "процессов".
  • 14. var deferred = $.Deferred(); function foo (msg) { console.log('foo: ' + msg); } function bar (msg) { console.log('bar: ' + msg); } deferred .done([foo, bar], foo) .fail(foo); $('button[name="resolve"]').click(function () { deferred.resolve('Ok...'); return false; }); $('button[name="reject"]').click(function () { deferred.reject('Not ok...'); return false; }); http://jsfiddle.net/sWvY6/
  • 15. var checkRequest = function (a1, a2) { var data = a1[0] + a2[0]; if (/Whip It/.test(data)) { alert( "We got what we came for!" ); } } $.when(ajax("/page1.php"), ajax("/page2.php")) .done(function (a1, a2) { // a1 and a2 are arguments resolved for // the page1 and page2 ajax requests, respectively. // Each argument is an array // with the following structure: [data, statusText, jqXHR] // a1[0] = "Whip", a2[0] = " It" checkRequest(a1, a2); }); // Alerts after both pages loaded. // Nasty hack $.when(ajax("/page1.php"), [" It"]]) .done(checkRequest); // Alerts when page1 is loaded.
  • 17. tornado.concurrent.Future Инкапсулирует результат асинхронной операции. Ближайший аналог - $.Callbacks. Отличие - $.Callbacks не имеет никакой связи с результатом. Привязка ни к объекту, а к процессу и его результату. Типичный подход для асинхронного программирования на сервере. Описание интерфейса - result() - возвращает результат операции, или выбрасывает ексепшен. - exception() - возвращает исключение, как объект. - add_done_callback(fn) - регистрирует колбек, который выполнится когда процесс будет завершен. С экземпляром Future в качестве аргумента. - done() - возвращает True, если процес завершен.
  • 18. tornado.ioloop Асинхронные процессы на сервере как правило связанны с сокетами. Сокет это объект, похожий на файл, который может находится в двух состояниях: запись и чтение. I/O Loop использует функцию ядра OS (epoll в Linux) для того, чтобы определить когда сокет изменит свое состояние.
  • 19. Описание интерфейса (не полное) - IOLoop.add_handler(fd, handler, events) - регистрирует колбек handler, который будет выполнен, когда сокет с дескриптором fd "сгенерирует" один из ивентов в списке events. - IOLoop.add_callback(callback, *args, **kwargs) - запускает колбек на следующей итерации IOLoop. - IOLoop.add_future(future, callback) - запускает колбек на следующей итерации IOLoop, после того, как future будет выполнено. - IOLoop.add_timeout(deadline, callback) - запускает кобек после наступления deadline.
  • 20. - Часть II Dzyga DispatcherProxy - работа с ивентами Promise, Once - работа с колбеками Task - абстракция для асинхронных процессов Loop, LoopTask - менеджер колбеков для ENTER_FRAME, реализация фоновых процессов, инкапсуляция интерактива для GUI.
  • 22. org.dzyga.event.DispatcherProxy - Расширение функционала EventDispatcher. - Облегчение работы с нативными флешовыми EventDispatcher. - Привязка добавленных к флешовому EventDispatcher обработчиков событий к конкретному классу с возможностью быстрого удаления зарегистрированных обработчиков. - Улучшение производительности, за счет группировки большого числа обработчиков в очередь. Но в большинстве случаев это будет работать, конечно, медленнее.
  • 23. Краткое описание: Дублирует функционал для добавления обработчиков событий а также проксирует нативные методы. Реализует IEventDispatcher. Для обработчиков добавляемых через DispatcherProxy создаются экземпляры класса EventListener, которые затем сохраняются в локальную для данного экземпляра коллекцию для обеспечения лучших возможностей манипуляции обработчиком, чем в нативном IEventDispatcher. Позволяет добавлять аргументы в обработчики событий, биндить их к другим объектам, а также регистрировать обработчики, которые автоматически удаляются после первого вызова.
  • 24. Описание интерфейса Добавление обработчика к проксируемому диспетчеру: function listen ( eventType:String, callback:Function, once:Boolean = false, thisArg:* = null, argArray:Array = null):IDispatcherProxy; Удаление обработчиков с проксируемого диспетчера: function stopListening ( eventType:String = '', callback:Function = null):IDispatcherProxy; Добавление обработчика к любому диспетчеру: function listenTo ( target:IEventDispatcher, eventType:String, callback:Function, once:Boolean = false, thisArg:* = null, argArray:Array = null):IDispatcherProxy;
  • 25. Удаление обработчиков, зарегистрированных данным прокси с одного или всех диспетчеров: function stopListeningTo ( target:IEventDispatcher = null, eventType:String = '', callback:Function = null):IDispatcherProxy; Триггер для простых ивентов: function triggerTo ( target:IEventDispatcher, eventType:String):IDispatcherProxy; Проверка зарегистрированных обработчиков: function isListeningTo ( target:IEventDispatcher = null, eventType:String = '', callback:Function = null):Boolean;
  • 26. Пример кода с синтаксическим сахаром dispatcher(d) .listen(MouseEvent.CLICK, onClick) .listen(MouseEvent.CLICK, onAnotherClick) .listen(MouseEvent.ROLL_OVER, onOver) .listen(MouseEvent.ROLL_OUT, onOut) .listen(MouseEvent.MOUSE_OUT, onOut) // Next callback will be removed after the first run. .listen( Event.ADDED_TO_STAGE, initView, true, null, ['target init']); dispatcher(d) .trigger(MouseEvent.CLICK) .trigger(MouseEvent.ROLL_OVER) .trigger(Event.ADDED_TO_STAGE) // Nothing happens there... .trigger(Event.ADDED_TO_STAGE);
  • 28. org.dzyga.callbacks.Promise - Замена и расширение функционала EventDispatcher. - Более явная реализация обработки асинхронных процессов promise можно объявлять свойством класса и/или интерфейса. - Реализация жестких однонаправленных связей между частями приложения: модуль добавляющий колбек в промис имеет доступ к модулю обработчику, модуль обработчик в обратную сторону - нет. Краткое описание Для добавляемых колбеков создаются инстансы класса Callback, которые помещаются в сортированный список. При вызове метода resolve все находящиеся в списке колбеки выполняются. Аргументы, заданные при добавлении колбека добавляются в конец списка аргументов, с которыми была вызван метод resolve.
  • 29. Описание интерфейса Добавление колбека: function callbackRegister ( callback:Function, once:Boolean = false, thisArg:* = null, argsArray:Array = null):IPromise; Удаление колбека: function callbackRemove (callback:Function = null):IPromise; Запуск колбеков (выполнение обещания): function resolve (... args):IPromise;
  • 30. private function firstCallback (inc:int = 1):void { _firstCounter += inc; } private function secondCallback (inc:int = 1):void { _secondCounter += inc; } [Test] public function testCallbackRegisterUniq ():void { var promise:Promise = new Promise(); promise .callbackRegister(firstCallback, false, null, [2]) .callbackRegister(firstCallback) .callbackRegister(secondCallback) .resolve(); // 3, if first callback added twice... assertEquals(2, _firstCounter); assertEquals(1, _secondCounter); promise.clear(); }
  • 31. org.dzyga.callbacks.Once Простейший субкласс Promise. Если Once был хоть один раз зарезолвлен, то все колбеки, добавляемые в будующем, запускаются сразу же после добавления. Как и Promise может быть зарезолвлен сколько угодно раз. Предусмотрена возможность повторного использования, при помощи метода reset().
  • 32. org.dzyga.callbacks.Task - Реализация асинхронных процессов - Инкапсуляция переменных и методов связанных с процессом. - Отделение функционала процесса от объектов, учавствующих в процессе. В теории, может вести к большим возможностям повторного использования кода. - Организация жестких однонаправленных связей между модулями.
  • 33. Краткое описание Cодержит промисы, которые резолвятся на разных стадиях процесса, и куда, внешние модули могут добавлять колбеки: - started - резолвится при запуске асинхронного процесса. done - резолвится при успешном завершении процесса. failed - резолвится при неправильном завершении процесса. finished - резолвится при любом завершении процесса, сразу после done или failed. - progress - резолвится на промежуточных стадиях процесса. Кроме промисов содержит еще поле state, т.е. Task является стейт-машиной.
  • 34. Описание интерфейса Запуск процесса, резолв промиса started с переданными аргументами: function start (... args):ITask; Переключение состояний процесса и резолв соответствующих промисов: function notify (... args):ITask; function resolve (... args):ITask; function reject (... args):ITask; Очистка всех промисов и сброс состояния процесса: function clear ():ITask; Возвращает одно из значений: TaskState.STARTED, TaskState.RESOLVED, TaskState.REJECTED или TaskState.IDLE: function get state ():String;
  • 36. - org.dzyga.eventloop.Loop Реализация фоновых процессов. Анимация. Обработка интерактива (замена MOUSE_MOVE) Ограничение количества запускаемых каждый фрейм обработчиков, с целью поддерживать заданный fps. Краткое описание: Позволяет запускать колбеки каждый фрейм, в том же фрейме, но в другом стеке, если есть возможность, или по таймауту. Поддерживает приоритеты. Если очередь колбеков выполняется дольше зависящего от fps времени - выполнение колбеков в этом фрейме прекращается, что позволяет поддерживать нужный фпс, жертвуя, например временем обработки фоновых процессов.
  • 37. Описание интерфейса Добавление колбека, который должен запускаться каждый фрейм: function frameEnterCall ( callback:Function, priority:uint = 1, thisArg:* = null, argsArray:Array = null):ILoopCallback; Добавление колбека, который должен запуститься в ближайшее возможное время: function call ( callback:Function, priority:uint = 1, thisArg:* = null, argsArray:Array = null):ILoopCallback; Добавление колбека по таймауту: function delayedCall ( callback:Function, delay:Number = 0, priority:uint = 1, thisArg:* = null, argsArray:Array = null):ILoopCallback;
  • 38. org.dzyga.eventlooop.LoopTask Служит для реализации задач, требующих значительного времени для выполнения: например - препроцессинг анимации. Метод run экземпляра класса будет выполнятся при помощи метода Loop.call каждый фрейм, столько раз, сколько позволяет время. Можно задавать приоритет выполнения колбека. Это субкласс Task. org.dzyga.eventlooop.FrameEnterTask Служит для реализации процессов, которые отвечают за обновление экрана (анимация) или за отслеживание происходящего на экране (мышь, положение движущихся объектов). Также как LoopTask должен содержать метод run, который при помощи метода Loop.frameEnterCall будет запускаться каждый фрейм.
  • 39. Исходник LoopTask (оптимизирован для просмотра) public function get callback ():Function { if (hasOwnProperty('run')) { return this['run']; } else { return FunctionUtils.identity; } } protected function loopCallbackRegister ():void { if (!_loopCallback) { _loopCallback = _loop.call( runner, priority); } } protected function runner ():void { if (state == TaskState.STARTED) { _result = callback.apply( thisArg, argsArray); } if (state == TaskState.STARTED) { loopCallbackRegister(); } } protected function loopCallbackCancel ():void { if (_loopCallback) { _loopCallback.cancel(); _loopCallback = null; } } protected function loopCallbackRemove ():void { if (_loopCallback) { _loop.callbackRemove(_loopCallback); _loopCallback = null; } } override public function start (...args):ITask { loopCallbackRegister(); return super.start.apply(this, args); } override public function resolve (...args):ITask { loopCallbackCancel(); return super.resolve.apply(this, args); } override public function reject (...args):ITask { loopCallbackCancel(); return super.reject.apply(this, args); } override public function clear ():ITask { loopCallbackRemove(); return super.clear(); }
  • 40. Пример реализации интерактива function loopCallbackRegister ():void { if (_trackingActive) { super.loopCallbackRegister(); } } function trackingEnable (e:Event = null):void { _trackingActive = true; loopCallbackRegister(); } function trackingDisable (e:Event = null):void { _trackingActive = false; loopCallbackCancel(); } function get trackingActive ():Boolean { return _trackingActive; } function run ():ICell { var cell:LevelCell = cellMap.cellGet( _view.mouseX, _view.mouseY); if (cell != _cell) { _cell = cell; notify(_cell); } return _cell; } function start (...args):ITask { _trackingActive = _view.active; _view .listen( LevelView.LEVEL_ACTIVATE_EVENT, trackingEnable) .listen( LevelView.LEVEL_DEACTIVATE_EVENT, trackingDisable); return super.start.apply(this, args); } function stop ():void { _view .stopListening( LevelView.LEVEL_DEACTIVATE_EVENT, trackingDisable) .stopListening( LevelView.LEVEL_ACTIVATE_EVENT, trackingEnable); _trackingActive = false; }