Асинхронный 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);