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

时间:2011-06-16 21:14:20

标签: jquery settimeout javascript

我想使用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秒钟,但是当我尝试实现它时,它会停止运行该函数。

2 个答案:

答案 0 :(得分:20)

传递...功能:))

使用匿名函数可能如下:

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回调需要一名警卫 - 一个简单的方法就是使用一个计数器。使用q中的setTimeout检查“当前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请求,直到获得回复或者“超时”已经过期且请求被视为无效为止。

答案 1 :(得分:0)

您也可以尝试这种方式

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">