Задержка до следующей функции в цепочке методов

Я пытаюсь узнать больше о цепочке методов в Javascript и хотел бы знать, как правильно создать задержку без jQuery для следующей функции в цепочке:

var foo = function() {
    this.delay = function(per) {
        setTimeout(start, per);
        return this;
    };
    this.start = function() {
        alert('start!');
    };
};

var bar = new foo().delay(1000).start();

person user1982408    schedule 16.01.2013    source источник
comment
Я не понимаю, почему кто-то проголосовал за закрытие. Это очень реальный и интересный вопрос.   -  person Denys Séguret    schedule 16.01.2013


Ответы (2)


Это нелегко сделать. jQuery использует специальную систему очередей.

Предположим, вы хотите сделать это без jQuery, вам придется реализовать очередь самостоятельно.

Например, эта очень упрощенная реализация:

var foo = function() {
    var queue = [];
    var timer;
    this.delay = function(per) {
      timer = setTimeout(function(){
        timer = 0;
        var f;
        while (f = queue.shift()) f();
      }, per);
      return this;
    };
    this.addFunction = function(f) {
      if (timer) queue.push(f);
      else f();
      return this;
    };
    this.start = function() {
       this.addFunction(function(){alert('start')});
       return this;
    };
};

Демонстрация


Если вы хотите связать другую функцию, не определенную в foo, вы можете сделать

var bar = new foo().delay(3000).start()
    .addFunction(function(){alert("another chained one")});

Демонстрация

person Denys Séguret    schedule 16.01.2013
comment
@user1982408 user1982408 Я отредактировал более эффективную очередь и пример цепочки с произвольной функцией. Обратите внимание, что это все еще упрощение и не направлено на замену очереди jQuery для всех случаев использования;) - person Denys Séguret; 16.01.2013
comment
сначала уму непостижимо, но я начинаю понимать логику - серьезно, спасибо - person user1982408; 16.01.2013

Это позволит вам связать несколько задержек: http://jsfiddle.net/z4Uyf/1/

js:

var foo = function() {

  var delayed = [];
  var delayExecution = false;
  var delayCount = 0;   
  function handleDelay(func){
    delayed.push(func);
    delayCount++;
  }

   function delayDone(){
     delayExecution = false;
     if( typeof(delayed[0]) == "function" ){
       delayed[0]();
       delayed.splice(0,1);
     }
     if( delayed.length > 0 ) delayExecution = true;
   }

   this.delay = function(per) {
        delayExecution = true;
        setTimeout(function(){
          delayDone();
        }, per);
        return this;
   };

  this.start = function() {
    if( delayExecution ){
     handleDelay(arguments.callee);
    }else{
     alert("start!");
    }
    return this;
  };
};

var bar = new foo().delay(1000).start().delay(5000).start();
person Travis J    schedule 16.01.2013