Javascript 执行当前ajax调用并中止所有以前的调用

Javascript 执行当前ajax调用并中止所有以前的调用,javascript,jquery,ajax,Javascript,Jquery,Ajax,我正在尝试构建一个自动完成的UI。有一个输入,其onkeyup函数对服务器执行ajax调用,以获取最相关的数据。但如果用户键入一个单词,比如说10个字符长,那么对于每个keyup都会进行一个ajax调用,我的对话框会刷新10次 我已经尝试对ajax调用使用abort()。当我中止前一个ajax调用时,调用没有被执行,但在执行最后一个调用之前它仍然等待10个调用,这使得用户体验非常糟糕 那么,有没有一种方法可以不延迟地执行当前的ajax调用 我的代码的一部分: var request_autoco

我正在尝试构建一个自动完成的UI。有一个输入,其on
keyup
函数对服务器执行ajax调用,以获取最相关的数据。但如果用户键入一个单词,比如说10个字符长,那么对于每个
keyup
都会进行一个ajax调用,我的对话框会刷新10次

我已经尝试对ajax调用使用
abort()
。当我中止前一个ajax调用时,调用没有被执行,但在执行最后一个调用之前它仍然等待10个调用,这使得用户体验非常糟糕

那么,有没有一种方法可以不延迟地执行当前的ajax调用

我的代码的一部分:

var request_autocomplete=jQuery.ajax({});
$('.review_autocomplete').keyup(function() {
    request_autocomplete.abort();
    request_autocomplete=jQuery.ajax({
        // DO something
    });
});

您可以采用您在问题中提出的方法来阻止示例3的呼叫,如下所示:

var calls = 0;
$('.review_autocomplete').keyup(function() {
    if (calls >3) {
        request_autocomplete.abort();
        request_autocomplete=jQuery.ajax({
            // DO something
        });
        calls = 0;
    }
    calls++;
});
但不建议使用这种方式,因为当用户想要键入
sample
时,用户键入
samp
at
p
ajax调用就会启动。当用户键入
l
e
时,什么也不会发生

如果您使用的是
jquery
Autocomplete
你可以使用

minLenght
这样您可以检查文本框的当前
lenght
,当用户键入至少3个字符时,您必须调用ajax请求

延迟
(在最后一次击键和ajax调用之间。通常2-300ms即可)

和使用


在对这个问题进行了快速搜索之后,我发现了另一种通过使用cache防止多个ajax调用autocomplete的方法。第一个是你的流产,看起来你已经流产了

第二是在这个过程中引入宽恕。您希望在用户停止键入时触发,而不是在每次按键时触发

您需要同时使用keyUp和keyDown。在keyUp上,设置一个触发提交的超时时间。给它大约700毫秒。在按下键时,清除超时

    var request_autocomplete=jQuery.ajax({});
    var forgiveness;

    // first your AJAX routine as a function
    var myServiceCall = function() {
       request_autocomplete.abort();
       request_autocomplete=jQuery.ajax({
            // DO something
    }

    // keyup 
    $('.review_autocomplete').keyup(function() {
        forgiveness = window.setTimeout(myServiceCall, 700);

      });
    });

    // key down
    $('.review_autocomplete').keydown(function() {
        window.clearTimeout(forgiveness);

      });
    });

这将持续设置一个超时,以便在每次钥匙打开时触发,但每次钥匙关闭时,它将取消该超时。这将使您的服务调用在用户停止键入或暂停时间过长之前不会触发。最终的结果是,您将终止一小部分呼叫。

您可以使用
globalTimeout
变量,通过
setTimeout()
clearTimeout()
重置该变量

这样,每当您的客户端按下键时,超时就会被清除,而当您的客户端释放键时,超时就会被再次设置,因此,在这种情况下,10毫秒后,只有在没有键操作的情况下才会调用
$.ajax()
。我承认,这不会阻止已经进行的
$.ajax()
调用,但是这可能并不重要,因为它们发生得非常快,并且因为这个示例阻止了将来的
$.ajax()
调用,只要客户端继续键入。

试试看

var count = {
    "start": 0,
    // future , by margin of `count.timeout`
    "complete": 0,
    // if no `keyup` events occur ,
    // within span of `count.timeout` 
    // `request_autocomplete()` is called
    // approximately `2` seconds , below ,
    // adjustable 
    "timeout" : 2
};
$('.review_autocomplete')
.focus()
.on("keyup", function (e) {
    elem = $(this);
    window.clearInterval(window.s);
    window.s = null;
    var time = function () {
        var t = Math.round($.now() / 1000);
        count.start = t;
        count.complete = t + count.timeout;
    };
    time();
    var request_autocomplete = function () {

        return jQuery.ajax({
            url: "/echo/json/",
            type: "POST",
            dataType: "json",
            data: {
                json: JSON.stringify({
                    "data": elem.val()
                })
            }
            // DO something
        }).done(function (data) {
            window.clearInterval(s);
            console.log("request complete", data);
            $("body").append("<br /><em>" + data.data + "</em>");
            elem.val("");
            count.start = count.complete = 0;
            console.log(count.start, count.complete);
        });
    };
    window.s = setInterval(function () {
        if (Math.round($.now() / 1000) > count.complete) {
            request_autocomplete();
            console.log("requesting data");
        };
    // increased to `1000` from `501`
    }, 1000);

});
var计数={
“开始”:0,
//future,以'count.timeout'为边距`
“完成”:0,
//如果没有发生“keyup”事件,
//在'count.timeout'的范围内
//调用了'request_autocomplete()'
//大约2秒钟,在下面,
//可调
“超时”:2
};
$('.review_autocomplete')
.focus()
.开启(“键控”,功能(e){
elem=$(本);
window.clearInterval(window.s);
window.s=null;
变量时间=函数(){
var t=Math.round($.now()/1000);
count.start=t;
count.complete=t+count.timeout;
};
时间();
var请求\u自动完成=函数(){
返回jQuery.ajax({
url:“/echo/json/”,
类型:“POST”,
数据类型:“json”,
数据:{
json:json.stringify({
“数据”:elem.val()
})
}
//做点什么
}).完成(功能(数据){
窗口。清除间隔(s);
控制台日志(“请求完成”,数据);
$(“body”).append(“
”+data.data+”); 元素val(“”); count.start=count.complete=0; console.log(count.start、count.complete); }); }; window.s=setInterval(函数(){ if(Math.round($.now()/1000)>count.complete){ 请求自动完成(); 控制台日志(“请求数据”); }; //从'501'增加到'1000'` }, 1000); });

JSFIDLE

我想这是行不通的,因为用户的输入速度要比从服务器获取时间快得多。因此,它将导致我的所有请求超时。我认为这个问题与我没有使用JQuery autocomplete的问题可能重复
var count = {
    "start": 0,
    // future , by margin of `count.timeout`
    "complete": 0,
    // if no `keyup` events occur ,
    // within span of `count.timeout` 
    // `request_autocomplete()` is called
    // approximately `2` seconds , below ,
    // adjustable 
    "timeout" : 2
};
$('.review_autocomplete')
.focus()
.on("keyup", function (e) {
    elem = $(this);
    window.clearInterval(window.s);
    window.s = null;
    var time = function () {
        var t = Math.round($.now() / 1000);
        count.start = t;
        count.complete = t + count.timeout;
    };
    time();
    var request_autocomplete = function () {

        return jQuery.ajax({
            url: "/echo/json/",
            type: "POST",
            dataType: "json",
            data: {
                json: JSON.stringify({
                    "data": elem.val()
                })
            }
            // DO something
        }).done(function (data) {
            window.clearInterval(s);
            console.log("request complete", data);
            $("body").append("<br /><em>" + data.data + "</em>");
            elem.val("");
            count.start = count.complete = 0;
            console.log(count.start, count.complete);
        });
    };
    window.s = setInterval(function () {
        if (Math.round($.now() / 1000) > count.complete) {
            request_autocomplete();
            console.log("requesting data");
        };
    // increased to `1000` from `501`
    }, 1000);

});