传递一个...函数:)
使用匿名函数可能如下:
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);
}
}
更智能的版本可能会在提交时读取 current 值,因为上面的代码总是会滞后一秒...
现在,假设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 请求来处理,直到获得回复或足够的“超时”到期并且请求被视为无效。