傳遞一個... :)功能
使用匿名函數可能如下:
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請求,直到獲得答覆或足夠的「超時」已過期並且請求被認爲無效。
我甚至不知道你在努力達到什麼目的。退後一步,思考你想要解決的問題。你開始ajax呼叫:它繼續。你在第一次完成之前立即開始另一個:它會發生什麼?它是否會因「不到一秒鐘」錯誤而失敗?它應該排隊等待一秒鐘後執行嗎?如果我在一秒鐘之前排隊1000次,該怎麼辦:你是否想要一個1000個等待ajax呼叫的隊列?某種意義上他們不會「衰敗」:他們要求的數據不再需要?不知何故,我不認爲setTimeout是問題。 – jmbucknall 2011-06-16 21:30:09