Именно это здание мы и будем сейчас выстраивать.
Как же именно можно осуществлять подобные вызовы? Мне пришло в голову следующее шаманство:
Создадим объект, в который будем складывать последовательно функции, которые необходимо вызвать, а по завершению коллбэка вызывать на исполнение следующую функцию.
Что нам понадобится?
- Массив, чтобы в нём хранить функции
- Добавление функции в массив
- Исполнение текущей функции
- Индикатор, для того, чтобы понимать, когда-же закончился коллбэк.
function SyncSequence(){
this.__functions__ = new Array();
}
SyncSequence.prototype={
add:function(func){
this.__functions__.push(func);
},
wrapCallback:function(callback){
var $this = this;
return function(){
callback.apply(null,arguments);
$this.runSequence();
}
},
runSequence:function(){
if(this.__functions__.length > 0){
this.__functions__.shift()();
}
}
}
В данном случае __functions__
является очередью, в который мы последовательно помещаем те вызовы, которые должны использовать.wrapCallback
создаёт функцию, которая заменит традиционный коллбэк. Основное её отличие заключается в том, что в конце исполнения данного ей коллбэка будет вызвана следующая функция в очереди.Ну а
runSequence
просто запускает верхушку на исполнение. Процесс создания очереди будет выглядеть примерно так.var ss = new SyncSequence();
ss.add(function(){
test(1,ss.wrapCallback(testCallback))
});
ss.add(function(){
test(2,ss.wrapCallback(testCallback))
});
ss.runSequence();
Конечно, не образец изящества, но всё-таки. Дополним код полусферическим примером:function test(arg,callback){
alert("Test started " + arg);
setTimeout(function(){
callback(arg + 100);
},1000);
}
function testCallback(arg){
alert("Test callback started " + arg);
}
При компоновке и запуске мне последовательно выдались 4 алерта:- Test started 1
- Test callback started 101
- Test started 2
- Test callback started 102
Будет нужно, подумаю что ещё можно будет добавить. А пока оставлю как есть.
И да, асинхронные вызовы снова стали синхронными. Троекратное ура.
Как всегда, исходные коды можно скачать.
В сторону promises/библиотеки q смотрели?
ОтветитьУдалить