使用 setTimeout 定期进行自动完成 AJAX 调用?
Posted
技术标签:
【中文标题】使用 setTimeout 定期进行自动完成 AJAX 调用?【英文标题】:Use setTimeout to periodically make autocomplete AJAX calls? 【发布时间】:2011-09-16 17:55:57 【问题描述】:我想使用一个 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 秒,但是当我尝试实现它时它停止运行该函数。
【问题讨论】:
我什至不确定您要达到的目标。退后一步,想想你要解决的问题。你开始一个 ajax 调用:它继续。你在第一个完成之前立即开始另一个:它应该发生什么?它是否应该因“不到一秒”的错误而失败?它应该排队等待一秒钟后执行吗?如果我在一秒钟之前将其中的 1000 个排队怎么办:你想要一个包含 1000 个等待 ajax 调用的队列吗?从某种意义上说,它们不会“衰减”:不再需要它们请求的数据吗?不知何故,我认为 setTimeout 不是问题。 【参考方案1】:传递一个...函数:)
使用匿名函数可能如下:
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 请求来处理,直到获得回复或足够的“超时”到期并且请求被视为无效。
【讨论】:
谢谢。你的回答超出了我的要求。这对我有很大帮助。 为什么这个答案没有得到更高的评价? ......更高!【参考方案2】:你也可以试试这个方法
var textInput = document.getElementById('input');
var timeout = null; // default set
textInput.onkeyup = function (e)
// If it has already been set cleared first.
clearTimeout(timeout);
// set timeout to 500ms
timeout = setTimeout(function ()
console.log('Input Value:', textInput.value);
, 500);
;
<input type="text" id="input">
【讨论】:
以上是关于使用 setTimeout 定期进行自动完成 AJAX 调用?的主要内容,如果未能解决你的问题,请参考以下文章