使用setTimeout定期进行自动完成AJAX调用?

我想使用setTimeout函数,以便Ajax调用最多每1秒进行一次。

这就是我所拥有的。 这显然不正确,但我不确定setTimeout函数是如何工作的。

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

我认为我应该使用clearTimeout,以便如果进行另一次调用,它将重置计时器并等待另一个1秒,但是当我尝试实现它时,它停止运行该函数。

通过…function:)

使用匿名函数可能如下:

 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回调需要一个后卫 – 一个简单的方法就是使用一个计数器。 使用setTimeoutq检查“当前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); } } 

更智能的版本可能会在提交时读取当前值,因为上面的代码总是落后一秒……

现在,假设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请求,直到获得答复或足够的“超时”已到期并且该请求被视为无效。