Асинхронные очереди в коде

в 15:56, , рубрики: Action Script, Flash-платформа, говнокод от юниора, упорядочивание кода, метки: ,

Доброго времени суток, Хабр и читатели.

image
Картинка для привлечения внимания.

В предыдущем (и первом моём посте) мы говорили про удобоваримость чтения написанного кода. То, зачем и был написан мной тот класс Instruction. В этом посте речь пойдёт уже о самом удобстве использования класса инструкции. А так же, о начале написания библиотеки утилиток.

Почти за два месяца после первой статьи, я успел столкнуться с разными задачами, связанными с последовательным выполнением скриптов. В процессе, класс инструкции оброс дополнительными функциями. А так же, на свет появилась ещё одна утилитка «Order». Порядок, или список задач — можно интерпретировать как угодно. Принцип работы схож с оригинальной инструкцией. Но, обо всём по порядку.

Инструкция обычная:

Код обычной инструкции

public function init():void {
	Async.instruction
	.add(commandOne, 'Param for commandOne')
	.add(commandTwo, 100500)
	.add(commandThree, [1, 2, 3, 4, 5])
	.execute(finalCommand, 'instruction executed successfully');
}
		
private function commandOne(completeCb:Function, string:String):void {
	trace(string); // 'Param for commandOne'
	completeCb();
}
		
private function commandTwo(completeCb:Function, number:int):void {
	trace(number); // 100500
	completeCb();
}
		
private function commandThree(completeCb:Function, array:Array):void {
	trace(array); // [1, 2, 3, 4, 5]
	completeCb();
}
		
private function finalCommand(input:String):void {
	trace(input); // 'instruction executed successfully'
}

Все функции выполняются последовательно. Так же, стоит учесть, что класс теперь выкинет ошибку в случае, если в одной из команд не будет присутствовать ни одного аргумента. По логике — один аргумент в вызываемой команде должен быть гарантированно — completeCallback, для передачи очереди следующей функции. Ещё момент — в команды и в финальную функцию параметры можно вообще не передавать в момент объявления инструкции.

Инструкция с кучей:

Код инструкции с кучей

public function init():void {
	Async.instruction.add(commandOne)
	.add(commandTwo, 100500)
	.add(commandThree, { type:'init data' } )
	.executeCollectingHeap(finalCommand);
}
		
private function commandOne(completeCb:Function):void {
	completeCb('commandOne', '1');
}
		
private function commandTwo(completeCb:Function, number:int):void {
	trace(number); // 100500
	completeCb('commandTwo', 2);
}
		
private function commandThree(completeCb:Function, object:Object):void {
	trace(JSON.stringify(object)); // { type:'init data' }
	completeCb('commandThree', {type:3});
}
		
private function finalCommand(heapResult:Array):void {
	trace(heapResult[0]); // ['commandOne', '1']
	trace(heapResult[1]); // ['commandTwo', 2]
	trace(heapResult[2]); // ['commandThree', {type:3}]
	trace('Instruction with heap executed successfully');
}

Особенность этого вида инструкции в том, что вызываемые коллбеки по завершению каждой из команд — могут передавать любое количество параметров. Внутри инструкции они бережно собираются в массив и в конце инструкции передаются финальной команде, что можно видеть по закомментированным подсказкам в коде. Так же, особенность в том, что в финальную команду на этапе объявления инструкции мы ничего не передаём.

Order, или список действий

Код списка действий

public function init() {
	Async.order
	.add(commandOne)
	.add(commandTwo)
	.add(commandThree)
	.execute(finalCommand);
}

private function commandOne(completeCb:Function):void {
	completeCb('string from commandOne');
}

private function commandTwo(completeCb:Function, string:String):void {
	trace(string); // string from commandOne
	completeCb(2, 'string from commandTwo');
}

private function commandThree(completeCb:Function, number:int, string:String):void {
	trace(number); // 2
	trace(string); // string from commandTwo
	completeCb();
}

private function finalCommand():void {
	trace('Order completed');
}

Этот вид я выделил отдельно, т.к. функционал инструкции был излишним, а городить кучу условий, впаивая новую логику — не захотелось. Суть здесь в том, что каждая команда по цепочке (по порядку) передаёт в следующую какие-либо данные. Очень удобно использовать в случае общения с api сервисов.

Весь код выложен на гитхаб. Заложено начало для небольшой (а, может быть, и большой в дальнейшем, кто знает?!) библиотеки.
Буду очень рад любой критике и комментариям в адрес библиотек. И крайне признателен за поправки или улучшения.

Автор: Frost47rus

Источник

Поделиться

* - обязательные к заполнению поля