限制$ .get()请求

dab*_*aba 0 ajax jquery

我定义了一个每次按下一个键时执行get请求的函数:

$('.form-control').keypress(function() {
    var o = $('#origin').val();
    var d = $('#destination').val();

    $('#directions').html('Wait, please...');

    $.get('/search', { origin: o, destination: d })
        .done(function(data) {
            $('#origin-info').html($('#origin').val());
            $('#destination-info').html($('#destination').val());

            $('#directions').html(data);
        });
    }
});
Run Code Online (Sandbox Code Playgroud)

但是,这是非常低效的,因为它每按一次键就会执行整个get请求.我不想在用户输入时查看所有请求.合乎逻辑的是限制给定一定时间或设置计时器的请求数量.然后当用户停止输入时,将执行最后一个请求.

我看了jQuery文档,get()但我没有看到这样的选项.

什么是最好的方法,我应该怎么做?

T.J*_*der 5

你有正确的想法.你没有在文档中看到它,get因为它不是它的工作,它是你的代码调用的工作 get:

var timer = 0;
$('.form-control').keypress(function() {
    clearTimeout(timer);
    timer = setTimeout(handleKeypress, 200);
});
function handleKeypress() {
    var o = $('#origin').val();
    var d = $('#destination').val();

    timer = 0;

    $('#directions').html('Wait, please...');

    $.get('/search', { origin: o, destination: d })
        .done(function(data) {
            $('#origin-info').html($('#origin').val());
            $('#destination-info').html($('#destination').val());

            $('#directions').html(data);
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

在那里,我们从一个timer带有值的变量开始0(因为0无效的计时器句柄clearTimeout默默地忽略).当用户按下一个键时,我们清除任何先前的计时器并设置一个计时器,以便稍后调用我们的功能200ms(五分之一秒).如果用户没有按另一个键,200ms后我们就会打电话; 但如果他们这样做,计时器会被取消(再次),我们会安排一个新计时器.


附注:以上假设您只有.form-control,就像您的代码中的情况一样.但是假设你有几个,并且有关该怎么做的信息get存储在.form-controls?上面的内容是不合适的,因为键入其中一个,按Tab键转到下一个,然后键入下一个将阻止第一个做它的工作.

在这种情况下,您将使用jQuery的方法将定时器句柄存储在元素本身上data:

$('.form-control').keypress(function() {
    var $this = $(this),
        timer = $this.data("keypress-timer");
    clearTimeout(timer); // clearTimeout will ignore `undefined`, so this is fine the first time
    timer = setTimeout(handleKeypress.bind(null, $this), 200);
});
function handleKeypress(control) {
    var container = control.closest(".container");
    var origin = container.find(".origin");
    var destination = container.find(".destination");
    var directions = container.find(".directions");
    var o = origin.val();
    var d = destination.val();

    control.data("keypress-timer", 0);

    directions.html('Wait, please...');

    $.get('/search', { origin: o, destination: d })
        .done(function(data) {
            container.find('.origin-info').html(o);
            container.find('.destination-info').html(d);

            directions.html(data);
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这只是一个假设的例子,假设它们在某种容器中,你可以在同一容器中找到其他相关字段......