18.12.2011, 05:23
|
|
Новичок
|
|
Регистрация: 05.09.2010
Сообщений: 2,298
|
|
Мой синхронный костыль
Продолжаю графоманить. На этот раз предлагаю свой способ поочередного вызова асинхронных функций (таймаутов, анимаций, аяксов и пр.) и избегания ужаса вложенных колбеков.
Для этого вызываем функцию waiting, затем по цепочке вызываем метод wait. Аргументом waiting и wait служит колбек, определенный в примере, как runNext. Его вызов запускает очередную порцию кода.
Для проверки работы откройте консоль.
(function(){
window.wait = function(first){
return new (function(){
var self = this;
var callback = function(){
var args;
if(self.deferred.length) {
args = [].slice.call(arguments);
args.unshift(callback);
self.deferred[0].apply(self, args);
self.deferred.shift();
}
}
this.wait = function(run){
this.deferred.push(run);
return self;
}
this.deferred = [];
first(callback);
})
}
/* Пример */
wait(function(runNext){
console.log('Run 1');
setTimeout(function(){
runNext(1,2); //передаем какие-нибудь аргументы в следующий вызов
}, 1000);
}).wait(function(runNext, a, b){
console.log('Run 2, a='+a+' b='+b ); //используем аргументы из предыдущего вызова
setTimeout(runNext, 1000);
}).wait(function(runNext){
console.log('Run 3');
setTimeout(function(){
console.log('End 3')
runNext();
}, 1000);
}).wait(function(runNext){
console.log('Run 4');
setTimeout(runNext, 1000);
}).wait(function(){
console.log('Last one');
});
})();
Пример с анимациями http://jsfiddle.net/finom/XSGub/37/
Последний раз редактировалось FINoM, 22.12.2011 в 07:16.
|
|
20.12.2011, 00:56
|
|
Модератор Всея Форума
|
|
Регистрация: 14.05.2009
Сообщений: 4,021
|
|
__________________
Болтовня ничего не стоит. Покажите мне код. — Linus Torvalds
влад.куркин.рф
|
|
20.12.2011, 06:33
|
|
Новичок
|
|
Регистрация: 05.09.2010
Сообщений: 2,298
|
|
B~Vladi, то что ты предложил несколько выходит за рамки моих знаний, поэтому компетентного ответа я дать не могу.
|
|
20.12.2011, 08:28
|
|
Модератор Всея Форума
|
|
Регистрация: 14.05.2009
Сообщений: 4,021
|
|
Я всё-таки допилю до юзабельного варианта и выложу.
__________________
Болтовня ничего не стоит. Покажите мне код. — Linus Torvalds
влад.куркин.рф
|
|
20.12.2011, 10:32
|
sinistral
|
|
Регистрация: 28.03.2011
Сообщений: 5,418
|
|
не слишком гибко, когда для вызова следующей функции из цепочки обязательно вызывать runNext. конечно, для передачи аргументов в следующий вызов она как раз подходит, но для того, чтобы просто вызвать следующую функцию (99%), потребутся вводить заветные буквы.
возможно ли ту функцию сделать необязательной ? как в этом случае будет обрабатываться время следующего вызова ?
|
|
20.12.2011, 19:28
|
|
Новичок
|
|
Регистрация: 05.09.2010
Сообщений: 2,298
|
|
melky,
А как узнать, что тот же таймаут завершился? Только по коллбеку.
Сообщение от melky
|
возможно ли ту функцию сделать необязательной ? как в этом случае будет обрабатываться время следующего вызова ?
|
Ты имеешь в виду, если не указан колбек, то вызывать следующую функцию сразу?
|
|
20.12.2011, 21:43
|
sinistral
|
|
Регистрация: 28.03.2011
Сообщений: 5,418
|
|
да. в этом случае можно указывать параметр, является ли блок кода полностью синхронным, или нет (ajax, напр.). если код async:false (default), если же он async:true - будьте добры тогда указать сами, когда он закончит исполнение (runNext)
|
|
20.12.2011, 22:39
|
|
Новичок
|
|
Регистрация: 05.09.2010
Сообщений: 2,298
|
|
Не знаю есть ли в этом смысл. В любом случае, придется писать
wait(function(){
this.async = false;
})
вместо
wait(function(){
this.next();
});
|
|
21.12.2011, 00:26
|
sinistral
|
|
Регистрация: 28.03.2011
Сообщений: 5,418
|
|
вы правы. оно нафиг не нужно, потому что (я прикинул) для этого придётся дописывать много кода в вашу функцию, и вообще, "овчинка не стоит выделки",т.к. при таком подходе передача аргументов осложняется.
|
|
21.12.2011, 13:36
|
|
Профессор
|
|
Регистрация: 09.07.2007
Сообщений: 304
|
|
экспериментировал с подобными штуками . функционал получался такой-же как у вас. Пробовал использовать в практике, но в итоге получается что проще классическим способом написать код или немного поменять алгоритм.
сейчас подумываю упростить. получается что-та вроде цепочки с паузами.
var sync = new ....;
setTimeout(sync(), 1000);
setTimeout(sync(), 100);
sync(function() {
});
setTimeout(sync(), 100);
var xx = sync();
sync(function() {
....
setTimeout(xx, 1000);
....
});
sync(function() {
});
|
|
|
|