2014-02-15 120 views
0

我想我的Ajax調用符文沒有常常是200毫秒,所以我寫了如何殺死計時器JS

if (update_timer != null) { 
    // do nothing 
} else { 
    // update_timer == null 
    update_timer = setTimeout (function() {perform_ajax_refresh()}, 200); 
} 

而且在perform_ajax_refresh()函數所做的:

function perform_ajax_refresh() 
{ 
    clearTimeout(update_timer); 
    console.log(update_timer); 
     // do ajax here 
} 

這些2線我努力殺死update_timer變量。什麼是正確的做法?我猜這個clearTimeout沒有任何意義,但是這是我的工作,將update_timer變量設置爲null。

+1

'clearTimeout'是完美的。 – leaf

+0

不,update_timer在它和我的if條件失敗後不爲空。 – Tigran

+1

所以,問題是:「爲什麼'update_timer'不會更改爲'null'?」對? – leaf

回答

2

JavaScript是按值傳遞的,因此clearTimeout不可能修改作爲參數傳遞的變量。

您的疑慮是有效的,解決問題的最簡單方法是在clearTimeout(update_timer)之後立即設置update_timer = null

(另外,要避免使用全局變量這種方式。當你和這個工作,嘗試重寫代碼,以便多個這樣的模塊可以在同一時間住一個網頁上。)

1

使用基於超時的解決方案,clearTimeout是要調用的函數。

讓我只是建議你另一種方式。如果您希望每n個msecs最多運行一次函數,則可以使用限制函數。這是一個這樣的函數功能的JavaScript實現。 http://remysharp.com/2010/07/21/throttling-function-calls/

通過使用它,你沒有實現運行Ajax請求函數內部的限制邏輯,使代碼更容易閱讀和推理,並避免依靠狀態,這是很好的。

var perform_ajax_refresh = function() 
    // your ajax call here 
} 
perform_ajax_refresh = throttle(perform_ajax_refresh, 200); 
//the original perform_ajax_refresh now gets only executed at most once every 200 msecs 

這裏是高階throttle功能,從在時間限制功能,執行「雷米夏普的博客」拍攝。

function throttle(fn, threshhold, scope) { 
    threshhold || (threshhold = 250); 
    var last, 
     deferTimer; 
    return function() { 
    var context = scope || this; 

    var now = +new Date, 
     args = arguments; 
    if (last && now < last + threshhold) { 
     // hold on to it 
     clearTimeout(deferTimer); 
     deferTimer = setTimeout(function() { 
     last = now; 
     fn.apply(context, args); 
     }, threshhold); 
    } else { 
     last = now; 
     fn.apply(context, args); 
    } 
    }; 
} 
0

清除函數體中的超時沒有任何作用,因爲超時已經發生在那個時候。嘗試這個相當簡單的構造:

function perform_ajax_refresh() 
{ 
    console.log("Refresh"); 
    // do ajax here 

    // new timeout 
    setTimeout(function() {perform_ajax_refresh()}, 200); 
} 
perform_ajax_refresh(); 
0

這個標題聽起來像一部電影!

這是一個「計時器演示」:http://jsfiddle.net/wared/uVbb2/

如您所見,有一個計時器設置爲零毫秒。這個訣竅很難解釋,但我相信它值得一點解釋。碰巧,我會說沒有這樣一個定時器,當倒計數到零時,whilespan.innerHTML = sec + ' sec'之前被執行......是的,的確是在與讀取方向相反的方向。因此,由於span.innerHTML = ''之後立即刪除倒計數,因此從不顯示「0秒」。

粗略地說,DOM任務默認排隊,直到沒有什麼可以執行javascript引擎。 「0」計時器允許通過在DOM任務之後將循環移動到執行隊列的末尾來繞過此默認行爲。我知道,它可以是混亂(和完全離題的方式),這樣,讓我建議你閱讀本:

這裏的代碼演示:

<button>click to play</button> <span></span> 
var tid, span, button; 
span = document.getElementsByTagName('span')[0]; 
button = document.getElementsByTagName('button')[0]; 
button.onclick = toggle; 

function play(sec) { 
    var i; 
    span.innerHTML = sec + ' sec'; 
    if (sec) { 
     tid = setTimeout(function() { 
      play(--sec); 
     }, 1000); 
    } else { 
     setTimeout(function() { 
      i = 0; 
      while (i++ < 5) alert('trapped :P'); 
      toggle(); 
     }, 0); 
    } 
} 

function toggle() { 
    if (tid) { 
     clearTimeout(tid); // phew... 
     tid = null; 
     span.innerHTML = ''; 
     button.style.color = 'black'; 
     button.innerHTML = 'click to play'; 
    } else { 
     play(5); 
     button.style.color = 'red'; 
     button.innerHTML = 'DO NOT click me again!'; 
    } 
}