2011-06-16 59 views
3

我想使用setTimeout函数,以便Ajax调用最多只能在1秒内完成。使用setTimeout定期进行自动完成AJAX调用?

这是我的。这显然是不正确的,但我不知道setTimeout函数是如何工作的。

function autoComplete(q, succ) 
{ 

    setTimeout(

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

    , 1000); 
} 

我认为我应该使用clearTimeout因此,如果另一个呼叫时,它会复位定时器并等待另一个1秒,但是当我试图实现这一点,停止运行的功能。

+0

我甚至不知道你在努力达到什么目的。退后一步,思考你想要解决的问题。你开始ajax呼叫:它继续。你在第一次完成之前立即开始另一个:它会发生什么?它是否会因“不到一秒钟”错误而失败?它应该排队等待一秒钟后执行吗?如果我在一秒钟之前排队1000次,该怎么办:你是否想要一个1000个等待ajax呼叫的队列?某种意义上他们不会“衰败”:他们要求的数据不再需要?不知何故,我不认为setTimeout是问题。 – jmbucknall 2011-06-16 21:30:09

回答

17

传递一个... :)功能

使用匿名函数可能如下:

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

+1

谢谢。你的回答比我所要求的要多。这将帮助我吨。 – TaylorMac 2011-06-16 21:31:28

+0

为什么这个答案的评分不高? ...高得多! – mkoistinen 2012-05-06 20:28:56