2011-06-16 38 views
3

我想使用setTimeout函數,以便Ajax調用最多隻能在1秒內完成。使用setTimeout定期進行自動完成AJAX調用?

這是我的。這顯然是不正確的,但我不知道setTimeout函數是如何工作的。

function autoComplete(q, succ) 
{ 

    setTimeout(

    if(q != "") { 
     $.ajax({type:"GET", 
      url: "php/search.php", 
      data: "q="+q, 
      success: succ 
     }); 
    } 

    , 1000); 
} 

我認爲我應該使用clearTimeout因此,如果另一個呼叫時,它會復位定時器並等待另一個1秒,但是當我試圖實現這一點,停止運行的功能。

+0

我甚至不知道你在努力達到什麼目的。退後一步,思考你想要解決的問題。你開始ajax呼叫:它繼續。你在第一次完成之前立即開始另一個:它會發生什麼?它是否會因「不到一秒鐘」錯誤而失敗?它應該排隊等待一秒鐘後執行嗎?如果我在一秒鐘之前排隊1000次,該怎麼辦:你是否想要一個1000個等待ajax呼叫的隊列?某種意義上他們不會「衰敗」:他們要求的數據不再需要?不知何故,我不認爲setTimeout是問題。 – jmbucknall 2011-06-16 21:30:09

回答

17

傳遞一個... :)功能

使用匿名函數可能如下:

var timeoutId 
function autoComplete(q, succ) 
{ 
    if (q) { 
     // stop previous timeouts 
     clearTimeout(timeoutId) 
     timeoutId = setTimeout(function() { 
      $.ajax({type:"GET", 
       url: "php/search.php", 
       data: "q="+q, 
       success: succ 
      }); 
     }, 1000); 
    } 
} 

注意我移動支票q之外。這不會一次運行兩次超時,但可能有多個正在進行的請求。爲了防止這種情況,success回調需要一個警衛 - 一個簡單的方法是使用計數器。使用setTimeout中的q檢查「當前的q」可能會導致細微的競爭條件。

var timeoutId 
var counter = 0 
function autoComplete(q, succ) 
{ 
    if (q) { 
     // Increment counter to maintain separate versions 
     counter++ 
     var thisCounter = counter 
     clearTimeout(timeoutId) 
     timeoutId = setTimeout(function() { 
      $.ajax({type:"GET", 
       url: "php/search.php", 
       data: "q="+q, 
       success: function() { 
        // Only call success if this is the "latest" 
        if (counter == thisCounter) { 
         succ.apply(this, arguments) 
        } 
       }, 
      }); 
     }, 1000); 
    } 
} 

智能版本可能會在提交因爲上面的代碼將永遠落後1秒後面的時間閱讀當前值...

現在,想象一下getQ是一個函數對象.. 。

var timeoutId 
var counter = 0 
function autoComplete(getQ, succ) 
{ 
    counter++ 
    var thisCounter = counter 
    clearTimeout(timeoutId) 
    timeoutId = setTimeout(function() { 
     var q = getQ() // get the q ... NOW 
     if (q) { 
      $.ajax({type:"GET", 
       url: "php/search.php", 
       data: "q="+q, 
       success: function() { 
        if (counter == thisCounter) { 
         succ.apply(this, arguments) 
        } 
       }, 
      }); 
     } 
    }, 1000); 
} 

// example usage 
autoComplete(function() { return $(elm).val() }, successCallback) 

快樂編碼。


有一點要考慮,在上面沒有解決,就是有仍可能在飛行中多次請求(在第二個例子中後衛只顯示瞭如何「拋棄」老迴應,不如何適當限制請求)。這可以通過短隊列來處理,並且可以防止提交新的AJAX請求,直到獲得答覆或足夠的「超時」已過期並且請求被認爲無效。

+1

謝謝。你的回答比我所要求的要多。這將幫助我噸。 – TaylorMac 2011-06-16 21:31:28

+0

爲什麼這個答案的評分不高? ...高得多! – mkoistinen 2012-05-06 20:28:56