2013-01-16 48 views
7

我想更多地瞭解法在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(); 
+3

我不明白爲什麼有人投票決定關閉。這是一個非常真實有趣的問題。 –

回答

7

這並不容易。 jQuery使用specific queue system

假設你想在沒有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; 
    }; 
}; 

Demonstration


如果你想鏈foo中沒有定義的另一個功能,你可以這樣做

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

Demonstration

+0

謝謝!那麼我怎樣才能將另一種方法鏈接到它呢? – user1982408

+0

@ user1982408我編輯了一個更強大的隊列和一個任意函數鏈接的例子。請注意,這仍然是簡單的,並不旨在取代所有用法的jQuery隊列;) –

+0

首先讓我浮想聯翩,但我開始理解邏輯 - 非常感謝你 – user1982408

2

這將讓您鏈多時滯: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();