传递一个... :)功能
使用匿名函数可能如下:
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