开发者问题收集

JQuery ajax .abort()

2015-10-01
837
  1. 用户点击搜索框
  2. 用户输入姓氏
  3. 如果文本框长度超过 2 个字符,则调用 ajax webservice

我遇到的问题是数据库速度很慢,包含数千条记录...

我可以输入“mcm”并等待,它会在 3 秒内返回 40 个结果。 我可以继续输入“mcmil”,它将在 1 秒内返回 11 个结果。

问题是,如果我从头开始一次性输入“mcmil”,我可以清楚地看到前 11 个结果,然后结果会随着“mcm”和“mcmi”的结果加载而跳转,大概是因为它们比较慢。

当 .keyup 触发时,我需要一种方法来检测当前是否正在发出 .ajax 请求并在发出新请求之前取消它。

$('#employeesearchbox').keyup(function () {

    if ($("#employeesearchbox").val().length > 2) {

        $.ajax({
            type: 'POST',
            url: './webservices/Contacts.asmx/ContactsDirectorySearch',
            data: JSON.stringify({ Surname: $("#employeesearchbox").val() }),
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            success: function (msg) {
                var employees = msg.d;
                $.each(employees, function (index, employee) {
                    $('#message').append("<li><a href='javascript:void(0);' class='response_object'>" + employee.Firstname + " " + employee.Department + "</a></li>");
                });
            },
            error: function (xhr, ajaxOptions, thrownError) {
                console.error("The error was: " + xhr.responseText);
            }
        });

    }

});

我看了这篇文章: abort-ajax-requests-using-jquery

它在 .ajax 之后直接取消请求,因为我可能想在下次按键时进行测试,当我添加此代码时得到“对象未定义”错误 - 因为对象不存在!

请帮忙

谢谢

var xhr = $.ajax({
 ...
});

//kill the request
xhr.abort()
3个回答

扩展我的评论 -

I'd be thinking about putting your ajax in maybe a half second setTimeout which is cleared with each new keypress. Most people will type more quickly than that. Also look at the answers to this question - Average Inter-Keypress time when typing and maybe look at the link in the comments of the accepted answer

例如 -

var delaySearch;
$('#employeesearchbox').keyup(function () {
  if ($("#employeesearchbox").val().length > 2) {
    clearTimeout(delaySearch);
    delaySearch = setTimeout(function() {
      $.ajax({
        type: 'POST',
        url: './webservices/Contacts.asmx/ContactsDirectorySearch',
        data: JSON.stringify({ Surname: $("#employeesearchbox").val() }),
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        success: function (msg) {
          var employees = msg.d;
          $.each(employees, function (index, employee) {
            $('#message').append("<li><a href='javascript:void(0);' class='response_object'>" + employee.Firstname + " " + employee.Department + "</a></li>");
          });
        },
        error: function (xhr, ajaxOptions, thrownError) {
          console.error("The error was: " + xhr.responseText);
        }
      });
    }, 500);
  }
});

我已将超时设置为 500 毫秒,但您可能需要根据数据库的性能和目标受众将超时时间延长一些。

John C
2015-10-01

按照这样的思路做怎么样?为每个发送的请求创建一个 ID,将其传递给服务器并从服务器返回。仅当请求不是太旧时才更新文档。

我仍然认为你应该考虑对这些请求进行反跳处理,基本上,在他们完成输入或做其他事情后的 300 毫秒内不要发送请求。

    var requestid = 0;
    $('#employeesearchbox').keyup(function () {

        if ($("#employeesearchbox").val().length > 2) {
            requestid++;
            $.ajax({
                type: 'POST',
                url: './webservices/Contacts.asmx/ContactsDirectorySearch',
                data: JSON.stringify({ Surname: $("#employeesearchbox").val(), requestid: requestid }),
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                error: function (xhr, ajaxOptions, thrownError) {
                    console.error("The error was: " + xhr.responseText);
                }
            }).done(function(msg){
                if(msg.requestid >= requestid){
                    var employees = msg.d;
                    $.each(employees, function (index, employee) {
                        $('#message').append("<li><a href='javascript:void(0);' class='response_object'>" + employee.Firstname + " " + employee.Department + "</a></li>");
                    });  
                }
            });

        }

    });
bingo
2015-10-01

感谢@robert,这是有效的代码。

xhr 在 .keyup 范围之外被声明为 null 按下按键后,我可以检查它是否不等于 null,并使用 .abort() 取消它

var xhr = null;

$('#employeesearchbox').keyup(function () {

    if ($("#employeesearchbox").val().length > 2) {

        if (xhr == null) {
            console.error("null");
        } else {
            //kill the request
            xhr.abort()
        }

        xhr = $.ajax({
            type: 'POST',
            url: './webservices/Contacts.asmx/ContactsDirectorySearch',
            data: JSON.stringify({ Surname: $("#employeesearchbox").val() }),
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            success: function (msg) {
                var employees = msg.d;
                $.each(employees, function (index, employee) {
                    $('#message').append("<li><a href='javascript:void(0);' class='response_object'>" + employee.Firstname + " " + employee.Department + "</a></li>");
                });
            },
            error: function (xhr, ajaxOptions, thrownError) {
                console.error("The error was: " + xhr.responseText);
            }
        });

    }

});
Scott
2015-10-01