Асинхронный callback
function async() {
// список ожидаемых сигналов
var args = Array.prototype.slice.call(arguments),
// callback-функция, которая будет вызывана при получении всех ожидаемых сигналов
callback = args.pop();
// Функция-обработчик сигналов
return function(v) {
console.log('recieved:', v);
// получаем сигнал и удаляем из списка ожидания
for (var i in args)
if (args[i] == v) args.splice(i, 1);
// если больше не осталось сигналов, вызываем callback
if (!args.length) callback();
}
}
var release = async('one', 'two', 'three', 'lastsignal', function(){ console.log('BINGO!'); });
setTimeout(function(){ release('one') }, 500);
setTimeout(function(){ release('two') }, 1000);
setTimeout(function(){ release('three') }, 1500);
setTimeout(function(){ release('lastsignal') }, 2500);
// По прошествию всех отложенных вызовов, будет вызвана callback функция
Приватные переменные через немедленно вызываемую функцию
var getUserUrl = function() {
var UserId = 666; // Переменная доступна только в теле функции
return function() {
console.log(UserId); // Удачно выведет айдищник пользователя
return 'http://domain.com/u'+UserId;
}
}() // Функция будет вызывана сразу после определения, и вернет в переменную новую функцию.
getUserId();
// вернет http://domain.com/u666
// при этом мы не сможем изменить переменную UserId, из вне, так как она является локальной (приватной) переменной.
Очередь на javascript
// Частенько нужно организовать очередь,
// для последовательного вызыва функций.
function Queue() {
this.q = [];
// Добавляет вызов в очередь
this.add = function(foo, scope, attr){
q.push(Array.prototype.slice.call(arguments));
}
// Проигрывает очередь
this.next = function() {
if (!this.q.length) return;
var opts = this.q.shift();
if (opts.length = 1) return opts[0]();
return opts[0].apply(opts[1], opts[2]||[]);
}
}
// Создаем экземпляр очереди
var q = new Queue();
// Функция, имитирующая анимацию с задержкой в 1 сек
var animaton = function(){
console.log('очень много анимации');
setTimeout(function(){
q.next(); // Крутим очередь дальше
}, 1000);
}
animation();
q.add(animation);
q.add(animation);
q.add(animation);
q.add(animation);
q.add(animation);
q.add(animation);
q.add(animation);
q.add(animation);
q.add(animation);